Vanillaxi opened a new pull request, #3403:
URL: https://github.com/apache/dubbo-go/pull/3403
## What is changed
This PR optimizes `common.URL.CloneWithFilter()` and `common.URL.MergeURL()`
to reduce unnecessary params copying and repeated locking on clone/merge paths.
Changes are limited to:
- `common/url.go`
- `common/url_test.go`
Main changes:
1. Add internal helper `copyURLValues`
- Deep-copies `url.Values`
- Preserves multi-value params
- Keeps `nil` input as `nil`
- Reuses the helper in `CopyParams()` without changing its public behavior
2. Add internal helper `valuesHasNonDefaultParam`
- Preserves the existing `GetNonDefaultParam()` semantics
- Treats missing keys or `values.Get(key) == ""` as not found
- Avoids replacing this behavior with a simple map key-existence check
3. Optimize `CloneWithFilter()`
- Avoids `RangeParams()` + calling `SetParam()` for each param
- Copies filtered params directly under a single read lock
- Deep-copies `[]string` values to preserve multi-value params
- Preallocates the params map for larger param sets to reduce map growth
- Avoids aggressive preallocation for small param sets
4. Optimize `MergeURL()`
- Keeps `mergedURL := c.Clone()` to preserve existing clone behavior
- Reuses the cloned local `mergedURL.params` directly
- Avoids the extra `mergedURL.GetParams()` deep copy
- Reads `anotherUrl.params` under a single read lock
- Deep-copies remote `[]string` values when merging
- Preserves existing timestamp, method params, attributes, `Methods`, and
`SubURL` behavior
5. Add tests
- `TestCloneWithFilterPreservesMultiValueParams`
- `TestMergeURLPreservesMultiValueParams`
- `TestMergeURLUsesNonDefaultParamSemantics`
## Why
`CloneWithFilter()` and `MergeURL()` are used in registry, directory,
configurator, and invoker update flows.
The previous implementation performed extra params map copies and repeated
locking through public helper methods. This PR keeps public `GetParams()` /
`CopyParams()` semantics unchanged while reducing internal copy/lock overhead.
## Benchmark
Benchmarks were measured on the same machine with Go 1.25.
Environment:
```text
goos: darwin
goarch: arm64
cpu: Apple M5
pkg: dubbo.apache.org/dubbo-go/v3/common
```
Command:
```bash
go test ./common -bench 'BenchmarkURL(CloneWithFilter|MergeURL)' -benchmem
-run '^$' -count=5
```
Summary of key results:
| Benchmark | before ns/op | after
ns/op | before B/op | after B/op | before allocs/op | after allocs/op |
| ------------------------------------------------ | ------------ |
----------- | ----------- | ---------- | ---------------- | --------------- |
| `CloneWithFilter/params_32` | 3309 | 2082
| 6232 | 3752 | 49 | 45 |
| `CloneWithFilter/params_256` | 32489 | 11701
| 47928 | 26408 | 279 | 269 |
| `CloneWithFilter/params_1024` | 122685 | 49558
| 207785 | 115280 | 1054 | 1039 |
| `CloneWithFilter/params_1024_exclude_20_percent` | 101994 | 62952
| 106120 | 62808 | 844 | 832 |
| `CloneWithFilter/params_1024_reserve_20_percent` | 378304 | 235029
| 25240 | 14632 | 221 | 213 |
| `MergeURL/params_1_with_method_params` | 6196 | 3916
| 6360 | 4016 | 103 | 69 |
| `MergeURL/params_32_with_method_params` | 13318 | 6487
| 19888 | 10416 | 218 | 116 |
| `MergeURL/params_256_with_method_params` | 65596 | 23168
| 103280 | 29456 | 1006 | 450 |
| `MergeURL/params_1024_with_method_params` | 284256 | 96447
| 447026 | 124472 | 3705 | 1604 |
Notable improvements:
```text
BenchmarkURLMergeURL/params_1024_with_method_params
ns/op: 284256 -> 96447 (~66.1% reduction)
B/op: 447026 -> 124472 (~72.2% reduction)
allocs/op: 3705 -> 1604 (~56.7% reduction)
BenchmarkURLCloneWithFilter/params_1024
ns/op: 122685 -> 49558 (~59.6% reduction)
B/op: 207785 -> 115280 (~44.5% reduction)
allocs/op: 1054 -> 1039 (~1.4% reduction)
```
## Test
```bash
go test ./common
```
Passed.
## Related issue
Fixes #3392
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]