Skip to content

feat: optimise normalize helper#341

Draft
wmundev wants to merge 2 commits into
mainfrom
feature/optimise-normalizehelper
Draft

feat: optimise normalize helper#341
wmundev wants to merge 2 commits into
mainfrom
feature/optimise-normalizehelper

Conversation

@wmundev
Copy link
Copy Markdown
Collaborator

@wmundev wmundev commented May 10, 2026

Changes

@codecov
Copy link
Copy Markdown

codecov Bot commented May 10, 2026

Codecov Report

❌ Patch coverage is 91.30435% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.01%. Comparing base (bd2cbd3) to head (01df556).

Files with missing lines Patch % Lines
csharp/PhoneNumbers/PhoneNumberUtil.cs 93.75% 0 Missing and 1 partial ⚠️
csharp/PhoneNumbers/PhoneNumberUtil.net.cs 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #341      +/-   ##
==========================================
+ Coverage   76.97%   77.01%   +0.04%     
==========================================
  Files          40       40              
  Lines        4712     4730      +18     
  Branches     1115     1120       +5     
==========================================
+ Hits         3627     3643      +16     
  Misses        851      851              
- Partials      234      236       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the internal normalization helper for modern .NET targets by introducing a Span-based NormalizeHelper(string, ...) implementation and conditionally compiling out the older StringBuilder-based string overload for those targets.

Changes:

  • Added a NET5+/netstandard2.1 NormalizeHelper(string, ...) overload that writes into a stack-allocated Span<char> and constructs the resulting string from the slice.
  • Wrapped the existing StringBuilder-based NormalizeHelper(string, ...) (in PhoneNumberUtil.cs) in a preprocessor guard so it only compiles for older targets.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
csharp/PhoneNumbers/PhoneNumberUtil.net.cs Adds Span/stackalloc-based NormalizeHelper(string, ...) for NET5+/netstandard2.1 builds.
csharp/PhoneNumbers/PhoneNumberUtil.cs Conditionally excludes the legacy NormalizeHelper(string, ...) for NET5+/netstandard2.1 so the new implementation is used.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 869 to 873
/// should be stripped from the number. If this is false, they
/// will be left unchanged in the number.</param>
/// <returns>The normalized string version of the phone number.</returns>
#if !(NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER)
private static string NormalizeHelper(string number, Func<char, char> normalizationReplacements, bool removeNonMatches)
Comment on lines +611 to +614
if (number.Length == 0) return string.Empty;
Span<char> result = stackalloc char[number.Length];
var resultLength = 0;
NormalizeHelper(ref result, ref resultLength, number, normalizationReplacements, removeNonMatches);
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 10, 2026

📊 Benchmark Results

Commit: 01df556 · Full run · Windows windows-latest

PR branch

BenchmarkDotNet v0.15.8, Windows 11 (10.0.26100.32690/24H2/2024Update/HudsonValley) (Hyper-V)
AMD EPYC 9V74 2.60GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.203
  [Host]             : .NET 9.0.15 (9.0.15, 9.0.1526.17522), X64 RyuJIT x86-64-v4
  .NET 8.0           : .NET 8.0.26 (8.0.26, 8.0.2626.16921), X64 RyuJIT x86-64-v4
  .NET 9.0           : .NET 9.0.15 (9.0.15, 9.0.1526.17522), X64 RyuJIT x86-64-v4
  .NET Framework 4.8 : .NET Framework 4.8.1 (4.8.9325.0), X64 RyuJIT VectorSize=256


Method Job Runtime PhoneNumberCount Mean Error StdDev Gen0 Gen1 Allocated
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 1000 2.175 ms 0.0084 ms 0.0074 ms 35.1563 - 582.48 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 1000 2.036 ms 0.0137 ms 0.0128 ms 35.1563 - 582.48 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 1000 6.073 ms 0.1189 ms 0.1503 ms 226.5625 23.4375 1397.58 KB
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 10000 22.339 ms 0.1932 ms 0.1807 ms 343.7500 - 5818.97 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 10000 21.026 ms 0.2063 ms 0.1929 ms 343.7500 - 5818.97 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 10000 61.425 ms 1.1720 ms 1.0390 ms 2222.2222 222.2222 13959.28 KB
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 100000 244.017 ms 4.9882 ms 14.5507 ms 3333.3333 - 58180.04 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 100000 209.584 ms 1.1425 ms 1.0128 ms 3333.3333 - 58180.04 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 100000 651.479 ms 12.9814 ms 25.9253 ms 22000.0000 2000.0000 139529.64 KB
main branch

BenchmarkDotNet v0.15.8, Windows 11 (10.0.26100.32690/24H2/2024Update/HudsonValley) (Hyper-V)
AMD EPYC 9V74 2.60GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.203
  [Host]             : .NET 9.0.15 (9.0.15, 9.0.1526.17522), X64 RyuJIT x86-64-v4
  .NET 8.0           : .NET 8.0.26 (8.0.26, 8.0.2626.16921), X64 RyuJIT x86-64-v4
  .NET 9.0           : .NET 9.0.15 (9.0.15, 9.0.1526.17522), X64 RyuJIT x86-64-v4
  .NET Framework 4.8 : .NET Framework 4.8.1 (4.8.9325.0), X64 RyuJIT VectorSize=256


Method Job Runtime PhoneNumberCount Mean Error StdDev Median Gen0 Gen1 Allocated
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 1000 2.275 ms 0.0442 ms 0.0574 ms 2.265 ms 35.1563 - 582.48 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 1000 2.083 ms 0.0394 ms 0.0602 ms 2.052 ms 35.1563 - 582.48 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 1000 5.953 ms 0.1153 ms 0.2275 ms 5.884 ms 226.5625 23.4375 1397.64 KB
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 10000 22.895 ms 0.3216 ms 0.2851 ms 22.827 ms 343.7500 - 5818.97 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 10000 20.608 ms 0.1151 ms 0.0899 ms 20.608 ms 343.7500 - 5818.97 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 10000 62.352 ms 1.2433 ms 1.4318 ms 61.944 ms 2250.0000 250.0000 13961.16 KB
ParseValidateAndFormatPhoneNumbers .NET 8.0 .NET 8.0 100000 226.525 ms 3.5386 ms 3.1369 ms 225.979 ms 3333.3333 - 58180.04 KB
ParseValidateAndFormatPhoneNumbers .NET 9.0 .NET 9.0 100000 210.023 ms 0.9001 ms 0.7979 ms 209.971 ms 3333.3333 - 58180.04 KB
ParseValidateAndFormatPhoneNumbers .NET Framework 4.8 .NET Framework 4.8 100000 640.129 ms 12.7096 ms 26.5296 ms 636.833 ms 22000.0000 2000.0000 139529.64 KB

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.

2 participants