🌐 AI搜索 & 代理 主页
Skip to content

Commit 3eb06c0

Browse files
committed
Speed up exemplar processing by moving exemplar storage inline into the Exemplar class
1 parent dcc971a commit 3eb06c0

File tree

7 files changed

+224
-67
lines changed

7 files changed

+224
-67
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System.Diagnostics;
2+
using BenchmarkDotNet.Attributes;
3+
using BenchmarkDotNet.Diagnosers;
4+
using Prometheus;
5+
6+
namespace Benchmark.NetCore;
7+
8+
[MemoryDiagnoser]
9+
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
10+
public class ExemplarBenchmarks
11+
{
12+
private readonly CollectorRegistry _registry;
13+
private readonly MetricFactory _factory;
14+
private readonly Counter _counter;
15+
16+
public ExemplarBenchmarks()
17+
{
18+
_registry = Metrics.NewCustomRegistry();
19+
_factory = Metrics.WithCustomRegistry(_registry);
20+
21+
// We provide the exemplars manually, without using the default behavior.
22+
_factory.ExemplarBehavior = ExemplarBehavior.NoExemplars();
23+
24+
_counter = _factory.CreateCounter("gauge", "help text");
25+
}
26+
27+
// Just establish a baseline - how much time/memory do we spend if not recording an exemplar.
28+
[Benchmark(Baseline = true)]
29+
public void Observe_NoExemplar()
30+
{
31+
_counter.Inc(123);
32+
}
33+
34+
// Just as a sanity check, this should not cost us anything extra and may even be cheaper as we skip the default behavior lookup.
35+
[Benchmark]
36+
public void Observe_EmptyExemplar()
37+
{
38+
_counter.Inc(123, Exemplar.None);
39+
}
40+
41+
private static readonly Exemplar.LabelKey CustomLabelKey1 = Exemplar.Key("my_key");
42+
private static readonly Exemplar.LabelKey CustomLabelKey2 = Exemplar.Key("my_key2");
43+
44+
// A manually specified custom exemplar with some arbitrary value.
45+
[Benchmark]
46+
public void Observe_CustomExemplar()
47+
{
48+
_counter.Inc(123, Exemplar.From(CustomLabelKey1.WithValue("my_value"), CustomLabelKey2.WithValue("my_value2")));
49+
}
50+
51+
// An exemplar extracted from the current trace context when there is no trace context.
52+
[Benchmark]
53+
public void Observe_ExemplarFromEmptyTraceContext()
54+
{
55+
_counter.Inc(123, Exemplar.FromTraceContext());
56+
}
57+
58+
[GlobalSetup(Targets = new[] { nameof(Observe_ExemplarFromTraceContext) })]
59+
public void Setup_ExemplarFromTraceContext()
60+
{
61+
new Activity("test activity").Start();
62+
63+
if (Activity.Current == null)
64+
throw new Exception("Sanity check failed.");
65+
}
66+
67+
// An exemplar extracted from the current trace context when there is a trace context.
68+
[Benchmark]
69+
public void Observe_ExemplarFromTraceContext()
70+
{
71+
_counter.Inc(123, Exemplar.FromTraceContext());
72+
}
73+
74+
[GlobalCleanup(Targets = new[] { nameof(Observe_ExemplarFromEmptyTraceContext), nameof(Observe_ExemplarFromTraceContext) })]
75+
public void Cleanup()
76+
{
77+
Activity.Current = null;
78+
}
79+
}

Prometheus/ChildBase.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Runtime.CompilerServices;
2+
13
namespace Prometheus;
24

35
/// <summary>
@@ -145,7 +147,10 @@ internal void RecordExemplar(Exemplar exemplar, ref ObservedExemplar storage, do
145147

146148
protected Exemplar GetDefaultExemplar(double value)
147149
{
148-
return _exemplarBehavior.DefaultExemplarProvider?.Invoke(Parent, value) ?? Exemplar.None;
150+
if (_exemplarBehavior.DefaultExemplarProvider == null)
151+
return Exemplar.None;
152+
153+
return _exemplarBehavior.DefaultExemplarProvider(Parent, value);
149154
}
150155

151156
// May be replaced in test code.

0 commit comments

Comments
 (0)