Merge pull request #394 from AArnott/eventsrc

Set up event source for easier perf investigations
This commit is contained in:
Andrew Arnott 2019-02-18 07:56:35 -08:00 коммит произвёл GitHub
Родитель e8bed2b3c0 b5d6109764
Коммит a02cd7bcd2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 130 добавлений и 1 удалений

Просмотреть файл

@ -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.