perf(core/stringx): replace manual char filter with strings.Map#5453
perf(core/stringx): replace manual char filter with strings.Map#5453kevwan merged 1 commit intozeromicro:masterfrom
Conversation
Below are benchmark results:BeforeAfter |
There was a problem hiding this comment.
Pull request overview
This PR updates core/stringx.Filter to use strings.Map for rune removal and adds a benchmark to evaluate the change.
Changes:
- Reimplemented
Filterusingstrings.Mapand renamed the predicate parameter fromfiltertoremove(doc/clarity). - Added
BenchmarkFilterto measure performance and allocations for always-remove vs never-remove predicates.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| core/stringx/strings.go | Switches Filter implementation to strings.Map and updates the parameter name/comment for clarity. |
| core/stringx/strings_test.go | Adds a benchmark intended to measure the new Filter behavior in two scenarios. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
kevwan
left a comment
There was a problem hiding this comment.
Review
Semantics — The predicate semantics are preserved: both old filter(r) == true (character was excluded via if !filter(x) guard) and new remove(r) == true mean "drop this rune". Renaming the parameter from filter to remove makes the intent clearer. ✓
Correctness — strings.Map(func(r rune) rune { if remove(r) { return -1 }; return r }, s) is the canonical Go idiom for filtered string construction. The implementation is equivalent to the previous version.
Performance — The old approach allocated a []rune(s) up front (full UTF-8 decode) and then re-encoded with string(chars[:n]), always paying the cost of a full rune slice regardless of how many characters are actually removed. strings.Map works byte-by-byte internally and can short-circuit allocation when no runes are removed. The "false" benchmark sub-test (no chars removed) will likely show a measurable improvement for ASCII-heavy strings.
Benchmark — The two sub-tests ("true" = all commas removed, "false" = nothing removed) cover both branches well. Running with -benchmem will confirm the allocation reduction for the no-remove path.
LGTM — clean, idiomatic simplification with a measurable performance benefit for the common no-op case.
The original Filter function used a manual []rune loop to remove characters
satisfying a predicate. This change:
reflect that the function removes characters for which remove(r) is true