docs: record SubList allocation strategy
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using System.Diagnostics;
|
||||
using NATS.Server.Benchmark.Tests.Harness;
|
||||
using NATS.Server.Subscriptions;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace NATS.Server.Benchmark.Tests.CorePubSub;
|
||||
|
||||
public class SubListMatchBenchmarks(ITestOutputHelper output)
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", "Benchmark")]
|
||||
public void SubListExactMatch_128Subjects()
|
||||
{
|
||||
using var subList = new SubList();
|
||||
for (var i = 0; i < 128; i++)
|
||||
subList.Insert(new Subscription { Subject = $"bench.exact.{i}", Sid = i.ToString() });
|
||||
|
||||
var (result, allocatedBytes) = Measure("SubList Exact Match (128 subjects)", "DotNet", "bench.exact.64".Length, 250_000, () =>
|
||||
{
|
||||
_ = subList.Match("bench.exact.64");
|
||||
});
|
||||
|
||||
BenchmarkResultWriter.WriteSingle(output, result);
|
||||
WriteAllocationSummary(allocatedBytes, result.TotalMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Benchmark")]
|
||||
public void SubListWildcardMatch_FanIn()
|
||||
{
|
||||
using var subList = new SubList();
|
||||
subList.Insert(new Subscription { Subject = "orders.created", Sid = "1" });
|
||||
subList.Insert(new Subscription { Subject = "orders.*", Sid = "2" });
|
||||
subList.Insert(new Subscription { Subject = "orders.>", Sid = "3" });
|
||||
subList.Insert(new Subscription { Subject = "orders.created.us", Sid = "4" });
|
||||
|
||||
var (result, allocatedBytes) = Measure("SubList Wildcard Match", "DotNet", "orders.created".Length, 250_000, () =>
|
||||
{
|
||||
_ = subList.Match("orders.created");
|
||||
});
|
||||
|
||||
BenchmarkResultWriter.WriteSingle(output, result);
|
||||
WriteAllocationSummary(allocatedBytes, result.TotalMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Benchmark")]
|
||||
public void SubListQueueMatch_MergedGroups()
|
||||
{
|
||||
using var subList = new SubList();
|
||||
subList.Insert(new Subscription { Subject = "jobs.run", Queue = "workers", Sid = "1" });
|
||||
subList.Insert(new Subscription { Subject = "jobs.*", Queue = "workers", Sid = "2" });
|
||||
subList.Insert(new Subscription { Subject = "jobs.>", Queue = "audit", Sid = "3" });
|
||||
|
||||
var (result, allocatedBytes) = Measure("SubList Queue Match", "DotNet", "jobs.run".Length, 250_000, () =>
|
||||
{
|
||||
_ = subList.Match("jobs.run");
|
||||
});
|
||||
|
||||
BenchmarkResultWriter.WriteSingle(output, result);
|
||||
WriteAllocationSummary(allocatedBytes, result.TotalMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Benchmark")]
|
||||
public void SubListRemoteInterest_WildcardLookup()
|
||||
{
|
||||
using var subList = new SubList();
|
||||
for (var i = 0; i < 64; i++)
|
||||
subList.ApplyRemoteSub(new RemoteSubscription($"remote.{i}.*", null, $"r{i}", "A"));
|
||||
|
||||
var (result, allocatedBytes) = Measure("SubList Remote Interest", "DotNet", "remote.42.created".Length, 250_000, () =>
|
||||
{
|
||||
_ = subList.HasRemoteInterest("A", "remote.42.created");
|
||||
});
|
||||
|
||||
BenchmarkResultWriter.WriteSingle(output, result);
|
||||
WriteAllocationSummary(allocatedBytes, result.TotalMessages);
|
||||
}
|
||||
|
||||
private static (BenchmarkResult Result, long AllocatedBytes) Measure(string name, string serverType, int bytesPerOperation, int iterations, Action operation)
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
for (var i = 0; i < 1_000; i++)
|
||||
operation();
|
||||
|
||||
var before = GC.GetAllocatedBytesForCurrentThread();
|
||||
var sw = Stopwatch.StartNew();
|
||||
for (var i = 0; i < iterations; i++)
|
||||
operation();
|
||||
sw.Stop();
|
||||
var allocatedBytes = GC.GetAllocatedBytesForCurrentThread() - before;
|
||||
|
||||
return (new BenchmarkResult
|
||||
{
|
||||
Name = name,
|
||||
ServerType = serverType,
|
||||
TotalMessages = iterations,
|
||||
TotalBytes = (long)iterations * bytesPerOperation,
|
||||
Duration = sw.Elapsed,
|
||||
}, allocatedBytes);
|
||||
}
|
||||
|
||||
private void WriteAllocationSummary(long allocatedBytes, long iterations)
|
||||
{
|
||||
output.WriteLine($"Allocated: {allocatedBytes:N0} B total | {allocatedBytes / (double)iterations:F2} B/op");
|
||||
output.WriteLine("");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user