Side-by-side performance benchmarks using NATS.Client.Core against both servers on ephemeral ports. Includes core pub/sub, request/reply latency, and JetStream throughput tests with comparison output and benchmarks_comparison.md results. Also fixes timestamp flakiness in StoreInterfaceTests by using explicit timestamps.
56 lines
2.4 KiB
C#
56 lines
2.4 KiB
C#
using System.Globalization;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace NATS.Server.Benchmark.Tests.Harness;
|
|
|
|
/// <summary>
|
|
/// Writes side-by-side benchmark comparison output to xUnit's ITestOutputHelper.
|
|
/// </summary>
|
|
public static class BenchmarkResultWriter
|
|
{
|
|
public static void WriteComparison(ITestOutputHelper output, BenchmarkResult goResult, BenchmarkResult dotnetResult)
|
|
{
|
|
var ratio = dotnetResult.MessagesPerSecond / goResult.MessagesPerSecond;
|
|
|
|
output.WriteLine($"=== {goResult.Name} ===");
|
|
output.WriteLine($"Go: {FormatRate(goResult.MessagesPerSecond)} msg/s | {goResult.MegabytesPerSecond:F1} MB/s | {goResult.Duration.TotalMilliseconds:F0} ms");
|
|
output.WriteLine($".NET: {FormatRate(dotnetResult.MessagesPerSecond)} msg/s | {dotnetResult.MegabytesPerSecond:F1} MB/s | {dotnetResult.Duration.TotalMilliseconds:F0} ms");
|
|
output.WriteLine($"Ratio: {ratio:F2}x (.NET / Go)");
|
|
|
|
if (goResult.Latencies is not null && dotnetResult.Latencies is not null)
|
|
{
|
|
output.WriteLine("");
|
|
output.WriteLine("Latency (us):");
|
|
output.WriteLine($" {"",8} {"P50",10} {"P95",10} {"P99",10} {"Min",10} {"Max",10}");
|
|
WriteLatencyRow(output, "Go", goResult.Latencies);
|
|
WriteLatencyRow(output, ".NET", dotnetResult.Latencies);
|
|
}
|
|
|
|
output.WriteLine("");
|
|
}
|
|
|
|
public static void WriteSingle(ITestOutputHelper output, BenchmarkResult result)
|
|
{
|
|
output.WriteLine($"=== {result.Name} ({result.ServerType}) ===");
|
|
output.WriteLine($"{FormatRate(result.MessagesPerSecond)} msg/s | {result.MegabytesPerSecond:F1} MB/s | {result.Duration.TotalMilliseconds:F0} ms");
|
|
|
|
if (result.Latencies is not null)
|
|
{
|
|
output.WriteLine("");
|
|
output.WriteLine("Latency (us):");
|
|
output.WriteLine($" {"",8} {"P50",10} {"P95",10} {"P99",10} {"Min",10} {"Max",10}");
|
|
WriteLatencyRow(output, result.ServerType, result.Latencies);
|
|
}
|
|
|
|
output.WriteLine("");
|
|
}
|
|
|
|
private static void WriteLatencyRow(ITestOutputHelper output, string label, LatencyPercentiles p)
|
|
{
|
|
output.WriteLine($" {label,8} {p.P50Us,10:F1} {p.P95Us,10:F1} {p.P99Us,10:F1} {p.MinUs,10:F1} {p.MaxUs,10:F1}");
|
|
}
|
|
|
|
private static string FormatRate(double rate)
|
|
=> rate.ToString("N0", CultureInfo.InvariantCulture).PadLeft(15);
|
|
}
|