Merge pull request #394 from AArnott/eventsrc
Set up event source for easier perf investigations
This commit is contained in:
Коммит
a02cd7bcd2
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PerfNetFramework
|
||||
{
|
||||
[EventSource(Name = "MessagePack-Benchmark")]
|
||||
internal sealed class BenchmarkEventSource : EventSource
|
||||
{
|
||||
private const int MessagePackSerializeStartEvent = 1;
|
||||
private const int MessagePackSerializeStopEvent = 2;
|
||||
private const int MessagePackDeserializeStartEvent = 3;
|
||||
private const int MessagePackDeserializeStopEvent = 4;
|
||||
private const int MessagePackSessionStartEvent = 5;
|
||||
private const int MessagePackSessionStopEvent = 6;
|
||||
|
||||
internal static readonly BenchmarkEventSource Instance = new BenchmarkEventSource();
|
||||
|
||||
private BenchmarkEventSource() { }
|
||||
|
||||
/// <summary>
|
||||
/// Marks the start of a serialization benchmark.
|
||||
/// </summary>
|
||||
/// <param name="impl">The library performing the serialization.</param>
|
||||
[Event(MessagePackSerializeStartEvent, Task = Tasks.Serialize, Opcode = EventOpcode.Start)]
|
||||
public void Serialize(string impl)
|
||||
{
|
||||
this.WriteEvent(MessagePackSerializeStartEvent, impl);
|
||||
}
|
||||
|
||||
[Event(MessagePackSerializeStopEvent, Task = Tasks.Serialize, Opcode = EventOpcode.Stop)]
|
||||
public void SerializeEnd()
|
||||
{
|
||||
this.WriteEvent(MessagePackSerializeStopEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the start of a deserialization benchmark.
|
||||
/// </summary>
|
||||
/// <param name="impl">The library performing the serialization.</param>
|
||||
[Event(MessagePackDeserializeStartEvent, Task = Tasks.Deserialize, Opcode = EventOpcode.Start)]
|
||||
public void Deserialize(string impl)
|
||||
{
|
||||
this.WriteEvent(MessagePackDeserializeStartEvent, impl);
|
||||
}
|
||||
|
||||
[Event(MessagePackDeserializeStopEvent, Task = Tasks.Deserialize, Opcode = EventOpcode.Stop)]
|
||||
public void DeserializeEnd()
|
||||
{
|
||||
this.WriteEvent(MessagePackDeserializeStopEvent);
|
||||
}
|
||||
|
||||
[Event(MessagePackSessionStartEvent, Task = Tasks.Session, Opcode = EventOpcode.Start)]
|
||||
public void Session(int count)
|
||||
{
|
||||
this.WriteEvent(MessagePackSessionStartEvent, count);
|
||||
}
|
||||
|
||||
[Event(MessagePackSessionStopEvent, Task = Tasks.Session, Opcode = EventOpcode.Stop)]
|
||||
public void SessionEnd()
|
||||
{
|
||||
this.WriteEvent(MessagePackSessionStopEvent);
|
||||
}
|
||||
|
||||
internal static class Tasks
|
||||
{
|
||||
internal const EventTask Session = (EventTask)1;
|
||||
internal const EventTask Serialize = (EventTask)2;
|
||||
internal const EventTask Deserialize = (EventTask)3;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ using Newtonsoft.Json;
|
|||
using System.Text;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace PerfnetFramework
|
||||
namespace PerfNetFramework
|
||||
{
|
||||
[ZeroFormattable]
|
||||
[ProtoBuf.ProtoContract]
|
||||
|
@ -55,6 +55,8 @@ namespace PerfnetFramework
|
|||
|
||||
class Program
|
||||
{
|
||||
internal static bool deserializing;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var p = new Person
|
||||
|
@ -76,9 +78,14 @@ namespace PerfnetFramework
|
|||
})
|
||||
.ToArray();
|
||||
|
||||
BenchmarkEventSource.Instance.Session(1);
|
||||
Benchmark(p);
|
||||
BenchmarkEventSource.Instance.SessionEnd();
|
||||
|
||||
Console.WriteLine();
|
||||
BenchmarkEventSource.Instance.Session(l.Length);
|
||||
Benchmark(l);
|
||||
BenchmarkEventSource.Instance.SessionEnd();
|
||||
}
|
||||
|
||||
static void Benchmark<T>(T target)
|
||||
|
@ -99,6 +106,8 @@ namespace PerfnetFramework
|
|||
Console.WriteLine();
|
||||
|
||||
Console.WriteLine("Serialize::");
|
||||
deserializing = false;
|
||||
|
||||
byte[] data = null;
|
||||
byte[] data0 = null;
|
||||
byte[] data1 = null;
|
||||
|
@ -212,6 +221,7 @@ namespace PerfnetFramework
|
|||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Deserialize::");
|
||||
deserializing = true;
|
||||
|
||||
using (new Measure("MsgPack-Cli"))
|
||||
{
|
||||
|
@ -344,12 +354,30 @@ namespace PerfnetFramework
|
|||
{
|
||||
this.label = label;
|
||||
System.GC.Collect(2, GCCollectionMode.Forced, blocking: true);
|
||||
if (!Program.deserializing)
|
||||
{
|
||||
BenchmarkEventSource.Instance.Serialize(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
BenchmarkEventSource.Instance.Deserialize(label);
|
||||
}
|
||||
|
||||
this.sw = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
sw.Stop();
|
||||
if (!Program.deserializing)
|
||||
{
|
||||
BenchmarkEventSource.Instance.SerializeEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
BenchmarkEventSource.Instance.DeserializeEnd();
|
||||
}
|
||||
|
||||
Console.WriteLine($"{ label,20} {sw.Elapsed.TotalMilliseconds} ms");
|
||||
|
||||
System.GC.Collect(2, GCCollectionMode.Forced, blocking: true);
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# Performance analysis
|
||||
|
||||
Build and use the release configuration of the project so you're measuring real perf with optimizations turned on:
|
||||
|
||||
dotnet build -c release .\sandbox\PerfNetFramework\
|
||||
|
||||
Use [PerfView](https://github.com/Microsoft/perfview/blob/master/documentation/Downloading.md) to analyze performance
|
||||
to look for opportunities to improve.
|
||||
When collecting ETL traces, use these settings in the Collect->Run dialog:
|
||||
|
||||
| Setting | Value |
|
||||
|-------------|-------|
|
||||
| Command | `dotnet run -c release -p .\sandbox\PerfNetFramework\ -f net461 --no-build`
|
||||
| Current Dir | `d:\git\messagepack-csharp` (or wherever your enlistment is)
|
||||
| Additional Providers | `*MessagePack-Benchmark`
|
||||
| No V3.X NGen | Checked
|
||||
|
||||
Start your investigation using the Events window to find the scenario that you're interested in,
|
||||
with these settings:
|
||||
|
||||
| Setting | Value |
|
||||
|------------|-------|
|
||||
| Filter | `MessagePack`
|
||||
| Columns to display | `count DURATION_MSEC impl`
|
||||
|
||||
Select the two `Time MSec` values that bound the scenario you're interested in, right-click and select CPU Stacks.
|
Загрузка…
Ссылка в новой задаче