Skip to content

Micro-optimisations: Improve memory usage for ReplaceMany string extension method - #23483

Merged
AndyButland merged 4 commits into
umbraco:mainfrom
patrickdemooij9:ReplaceManyImprovement
Aug 5, 2026
Merged

AndyButland merged 4 commits into
umbraco:mainfrom
patrickdemooij9:ReplaceManyImprovement

Conversation

@patrickdemooij9

Copy link
Copy Markdown
Contributor

Prerequisites

  • I have added steps to test this contribution in the description below (Added extra unit test case & existing unit tests are succeeding)

Description

The old ReplaceMany was using multiple .Replace() functions, each of them creating a new string in memory. As it's just a char for char replacement, we can change this by constructing a single string and replacing them as we are constructing the string resulting in only one string being allocated.

I also reran all the benchmarks for the ReplaceMany and updated the timings (which also shows DotNet is just a lot faster in general :P). Main ones regarding this code are:

short text, short replacement:

Method Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
'String.ReplaceMany w/chars - Aggregate' 68.65 ns 46.32 ns 2.539 ns 1.00 0.04 0.0185 240 B 1.00
'String.ReplaceMany w/chars - For Loop' 66.85 ns 10.66 ns 0.584 ns 0.97 0.03 0.0190 240 B 1.00
'String.ReplaceMany w/chars - String Create' 39.22 ns 13.80 ns 0.757 ns 0.57 0.02 0.0037 48 B 0.20

long text, short replacement:

Method Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
'String.ReplaceMany w/chars - Aggregate' 426.0 ns 856.13 ns 46.93 ns 1.01 0.14 0.5656 6.97 KB 1.00
'String.ReplaceMany w/chars - For Loop' 415.0 ns 230.56 ns 12.64 ns 0.98 0.10 0.5658 6.97 KB 1.00
'String.ReplaceMany w/chars - String Create' 389.8 ns 177.93 ns 9.75 ns 0.92 0.09 0.1401 1.74 KB 0.25

@github-actions

Copy link
Copy Markdown

Hi there @patrickdemooij9, thank you for this contribution! 👍

While we wait for one of the Core Collaborators team to have a look at your work, we wanted to let you know about that we have a checklist for some of the things we will consider during review:

  • It's clear what problem this is solving, there's a connected issue or a description of what the changes do and how to test them
  • The automated tests all pass (see "Checks" tab on this PR)
  • The level of security for this contribution is the same or improved
  • The level of performance for this contribution is the same or improved
  • Avoids creating breaking changes; note that behavioral changes might also be perceived as breaking
  • If this is a new feature, Umbraco HQ provided guidance on the implementation beforehand
  • 💡 The contribution looks original and the contributor is presumably allowed to share it

Don't worry if you got something wrong. We like to think of a pull request as the start of a conversation, we're happy to provide guidance on improving your contribution.

If you realize that you might want to make some changes then you can do that by adding new commits to the branch you created for this work and pushing new commits. They should then automatically show up as updates to this pull request.

Thanks, from your friendly Umbraco GitHub bot 🤖 🙂

Comment thread src/Umbraco.Core/Extensions/StringExtensions.Manipulation.cs Outdated
@AndyButland AndyButland changed the title Improve memory usage for ReplaceMany Micro-optimisations: Improve memory usage for ReplaceMany string extension method Aug 5, 2026

@AndyButland AndyButland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this @patrickdemooij9 - looks good and worth having. I've just pushed an update with an increase in test coverage, and verified them on the before and after code.

@AndyButland
AndyButland enabled auto-merge (squash) August 5, 2026 14:36
@AndyButland
AndyButland merged commit 07a5769 into umbraco:main Aug 5, 2026
29 checks passed
AndyButland added a commit that referenced this pull request Aug 5, 2026
…tension method (#23483)

* Improve memory usage for ReplaceMany

* Small improvement

* Use actual implementation in benchmark.

* Further test cases to increase coverage and verify no risk of regression.

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
@AndyButland

Copy link
Copy Markdown
Contributor

Cherry-picked to v17/dev.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants