Description
LabelNamer.Build() allocates a new string on every call, even when the label name is already compliant. This causes significant memory fragmentation, especially in high-frequency label transformation
scenarios (e.g., OpenTelemetry Collector Contrib's Prometheus remote write exporter).
Steps to Reproduce
- Use OpenTelemetry Collector to collect a large number of metrics
- Observe significant memory fragmentation in the process
Analysis
Current Build() implementation:
normalizedName := sanitizeLabelName(label, ln.PreserveMultipleUnderscores)
sanitizeLabelName uses strings.Builder internally to create a new string on every call:
- Allocates new memory
- Copies the entire label string
- Returns a new string
Expected Behavior
For already-compliant labels (e.g., http_method), should:
- Return the original string directly without allocation
- Or reuse cached transformation results
Reference Implementation
VictoriaMetrics' FastStringTransformer uses sync.Map to cache transformation results, avoiding repeated allocations.
Environment
- OpenTelemetry Collector Contrib
- Prometheus remote write exporter
- High-cardinality metrics scenario
Related Components
- LabelNamer.Build()
- sanitizeLabelName()
Description
LabelNamer.Build()allocates a new string on every call, even when the label name is already compliant. This causes significant memory fragmentation, especially in high-frequency label transformationscenarios (e.g., OpenTelemetry Collector Contrib's Prometheus remote write exporter).
Steps to Reproduce
Analysis
Current
Build()implementation:sanitizeLabelName uses strings.Builder internally to create a new string on every call:
Expected Behavior
For already-compliant labels (e.g., http_method), should:
Reference Implementation
VictoriaMetrics' FastStringTransformer uses sync.Map to cache transformation results, avoiding repeated allocations.
Environment
Related Components