Skip to content

xds: pre-parse custom metric names in WRR load balancer#12773

Open
sauravzg wants to merge 1 commit intogrpc:masterfrom
sauravzg:wrr-custom-metrics-perf-opt
Open

xds: pre-parse custom metric names in WRR load balancer#12773
sauravzg wants to merge 1 commit intogrpc:masterfrom
sauravzg:wrr-custom-metrics-perf-opt

Conversation

@sauravzg
Copy link
Copy Markdown
Collaborator

Introduce ParsedMetricName in MetricReportUtils to pre-parse configured custom metric names into Enums and key Strings on config initialization in WeightedRoundRobinLoadBalancerConfig, avoiding String parsing operations in the data path.

This has been done by a combination of a few things

  • Streams -> loop
  • OptionalDouble -> double
  • Pre parsing instead of hot path substring

OrcaReportListener now utilizes pre-parsed ParsedMetricName objects during getCustomMetricUtilization to prevent OptionalDouble heap allocations on the hot path.

Updated test coverage in MetricReportUtilsTest and WeightedRoundRobinLoadBalancerTest.

JMH Benchmark Report: MetricReportUtils Optimization

We performed a benchmark comparison of four different custom metric resolution implementations in the Weighted Round Robin (WRR) load balancer.

Benchmark Results

Benchmark Variant Average Latency Normalized Heap Allocations Speedup
Baseline (String + Streams) 174.46 ns/op 704.00 B/op 1x
ParsedMetricName + Streams 148.95 ns/op 608.00 B/op ~1.1x
String + Loop 81.61 ns/op 240.00 B/op ~2.1x
ParsedMetricName + Loop 52.92 ns/op 144.00 B/op ~3.2x
ParsedMetricName + Unboxed Loop 43.76 ns/op ≈ 0.00 B/op ~4.0x

@sauravzg
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the custom metric handling in the WeightedRoundRobinLoadBalancer to improve performance. It introduces a ParsedMetricName class and a MetricType enum to pre-parse metric name strings into structured objects during configuration. This change eliminates the need for repeated string parsing and prefix checking whenever a load report is processed. The MetricReportUtils utility was updated to use these parsed types, and the load balancer's internal listeners and pickers were adjusted accordingly. I have no feedback to provide.

@sauravzg sauravzg force-pushed the wrr-custom-metrics-perf-opt branch from e20e58c to 822c7e8 Compare April 23, 2026 11:06
@sauravzg
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the WeightedRoundRobinLoadBalancer to use pre-parsed metric names, improving efficiency by avoiding repeated string parsing during load report processing. It introduces a ParsedMetricName class and updates MetricReportUtils to handle metric lookups using these typed objects. Feedback was provided to improve the robustness of the parsing utility by explicitly handling null input.

Comment thread xds/src/main/java/io/grpc/xds/internal/MetricReportUtils.java
Introduce ParsedMetricName in MetricReportUtils to pre-parse configured
custom metric names into Enums and key Strings on config initialization
in WeightedRoundRobinLoadBalancerConfig, avoiding String parsing
operations in the data path.

This has been done by a combination of a few things

- Streams -> loop
- OptionalDouble -> double
- Pre parsing instead of hot path substring

OrcaReportListener now utilizes pre-parsed ParsedMetricName objects
during getCustomMetricUtilization to prevent OptionalDouble heap
allocations on the hot path.

Updated test coverage in MetricReportUtilsTest and
WeightedRoundRobinLoadBalancerTest.

# JMH Benchmark Report: MetricReportUtils Optimization

We performed a benchmark comparison of four different custom metric
resolution implementations in the Weighted Round Robin (WRR) load
balancer.

## Benchmark Results

| Benchmark Variant                     | Average Latency | Normalized Heap Allocations | Speedup   |
| :------------------------------------ | :-------------- | :-------------------------- | :-------- |
| **Baseline (`String` + Streams)**     | 174.46 ns/op    | 704.00 B/op                 | 1x        |
| **`ParsedMetricName` + Streams**      | 148.95 ns/op    | 608.00 B/op                 | ~1.1x     |
| **`String` + Loop**                   | 81.61 ns/op     | 240.00 B/op                 | ~2.1x     |
| **`ParsedMetricName` + Loop**         | 52.92 ns/op     | 144.00 B/op                 | ~3.2x     |
| **`ParsedMetricName` + Unboxed Loop** | **43.76 ns/op** | **≈ 0.00 B/op**             | **~4.0x** |

---
@sauravzg sauravzg force-pushed the wrr-custom-metrics-perf-opt branch from 822c7e8 to c7d6502 Compare April 23, 2026 13:10
@sauravzg
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the custom metric handling in the WeightedRoundRobinLoadBalancer by pre-parsing metric names. It introduces a ParsedMetricName class and a MetricType enum in MetricReportUtils to replace string-based lookups with a more efficient typed approach. The WeightedRoundRobinLoadBalancerConfig now parses and validates metric names upon initialization, ignoring and logging any invalid entries. Corresponding updates were made to the load balancer's picker and ORCA report listener, as well as associated unit tests. I have no feedback to provide as there were no review comments to assess.

@sauravzg
Copy link
Copy Markdown
Collaborator Author

Update: I forgot that I sent it out and since it's pretty late weekend right now, I'll assign a reviewer once I am back next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant