162 lines
5.0 KiB
C#
162 lines
5.0 KiB
C#
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace Flax.Build
|
|
{
|
|
/// <summary>
|
|
/// Inserts a profiling event for the given code scope.
|
|
/// </summary>
|
|
public class ProfileEventScope : IDisposable
|
|
{
|
|
private int _id;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ProfileEventScope"/> class.
|
|
/// </summary>
|
|
/// <param name="name">The event name.</param>
|
|
public ProfileEventScope(string name)
|
|
{
|
|
_id = Profiling.Begin(name);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the profiling event.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Profiling.End(_id);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The build system performance profiling tools.
|
|
/// </summary>
|
|
public static class Profiling
|
|
{
|
|
/// <summary>
|
|
/// The performance event data.
|
|
/// </summary>
|
|
public struct Event
|
|
{
|
|
/// <summary>
|
|
/// The event name.
|
|
/// </summary>
|
|
public string Name;
|
|
|
|
/// <summary>
|
|
/// The event start time.
|
|
/// </summary>
|
|
public DateTime StartTime;
|
|
|
|
/// <summary>
|
|
/// The event duration.
|
|
/// </summary>
|
|
public TimeSpan Duration;
|
|
|
|
/// <summary>
|
|
/// The event call depth (for parent-children events evaluation).
|
|
/// </summary>
|
|
public int Depth;
|
|
}
|
|
|
|
private static int _depth;
|
|
private static readonly List<Event> _events = new List<Event>(1024);
|
|
|
|
/// <summary>
|
|
/// Begins the profiling event.
|
|
/// </summary>
|
|
/// <param name="name">The name.</param>
|
|
/// <returns>The event id. Used by <see cref="End"/> callback.</returns>
|
|
public static int Begin(string name)
|
|
{
|
|
Event e;
|
|
e.Name = name;
|
|
e.StartTime = DateTime.Now;
|
|
e.Duration = TimeSpan.Zero;
|
|
e.Depth = _depth++;
|
|
_events.Add(e);
|
|
return _events.Count - 1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the profiling event.
|
|
/// </summary>
|
|
/// <param name="id">The event identifier returned by <see cref="Begin"/>.</param>
|
|
public static void End(int id)
|
|
{
|
|
var endTime = DateTime.Now;
|
|
var e = _events[id];
|
|
e.Duration = endTime - e.StartTime;
|
|
_events[id] = e;
|
|
_depth--;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the recorded profiler events.
|
|
/// </summary>
|
|
public static void LogStats()
|
|
{
|
|
TimeSpan add = TimeSpan.Zero;
|
|
for (int i = 0; i < _events.Count; i++)
|
|
{
|
|
var e = _events[i];
|
|
|
|
if (i + 1 < _events.Count && _events[i + 1].Depth == e.Depth && _events[i + 1].Name == e.Name)
|
|
{
|
|
// Merge two events times
|
|
add += e.Duration;
|
|
continue;
|
|
}
|
|
|
|
string str = string.Empty;
|
|
while (e.Depth-- > 0)
|
|
str += " ";
|
|
str += e.Name;
|
|
str += " ";
|
|
str += e.Duration + add;
|
|
add = TimeSpan.Zero;
|
|
|
|
Log.Info(str);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates the Trace Event file for profiling build system events.
|
|
/// </summary>
|
|
public static void GenerateTraceEventFile()
|
|
{
|
|
var traceEventFile = Configuration.TraceEventFile;
|
|
if (traceEventFile.Length == 0)
|
|
{
|
|
var logFile = Configuration.LogFile.Length != 0 ? Configuration.LogFile : "Cache/Intermediate/Log.txt";
|
|
traceEventFile = Path.ChangeExtension(logFile, ".trace.json");
|
|
}
|
|
var path = Path.GetDirectoryName(traceEventFile);
|
|
if (!string.IsNullOrEmpty(path) && !Directory.Exists(path))
|
|
Directory.CreateDirectory(path);
|
|
|
|
Log.Info("Saving trace events to " + traceEventFile);
|
|
var contents = new StringBuilder();
|
|
|
|
contents.Append("{\"traceEvents\": [");
|
|
var startTime = _events.Count != 0 ? _events[0].StartTime : DateTime.MinValue;
|
|
for (int i = 0; i < _events.Count; i++)
|
|
{
|
|
var e = _events[i];
|
|
|
|
contents.Append($"{{ \"pid\":1, \"tid\":1, \"ts\":{(int)((e.StartTime - startTime).TotalMilliseconds * 1000.0)}, \"dur\":{(int)(e.Duration.TotalMilliseconds * 1000.0)}, \"ph\":\"X\", \"name\":\"{e.Name}\", \"args\":{{ \"startTime\":\"{e.StartTime.ToShortTimeString()}\" }} }}\n");
|
|
|
|
if (i + 1 != _events.Count)
|
|
contents.Append(",");
|
|
}
|
|
contents.Append("]}");
|
|
|
|
File.WriteAllText(traceEventFile, contents.ToString());
|
|
}
|
|
}
|
|
}
|