-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce allocations in String::sprintf
#94558
Reduce allocations in String::sprintf
#94558
Conversation
dd3698b
to
82dec21
Compare
String::sprintf
Related: #93697, this PR supersedes that one |
I feel like intead of |
Totally agree. Adding appending APIs would be helpful. Also, being able to keep the memory around for a |
There's quite a lot of examples of |
82dec21
to
0d604d8
Compare
Just passing by. A few thoughts:
The In other words, at some point my view is that it would be ideal that We could even have a copy-on-write specialization which is not thread-safe, which may be a better fit for strings. I'd say that all of this would need to be discussed carefully because there are things yelling to be improved, such as these vector types getting more telling names and finding out the most precise set of features each needs across the codebase. |
Discussion of future improvements aside, I think we can go ahead and merge this once it is updated to use |
I'll fix that. As an aside, I wrote a blog about |
This prevents an allocation of a new string for every character. Additionally, use some static constants for padding and sign characters
0d604d8
to
67eb6be
Compare
@RandomShaper / @clayjohn changed to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally, it works as expected.
Testing project: test_pr_94558.zip
Benchmark
PC specifications
- CPU: Intel Core i9-13900K
- GPU: NVIDIA GeForce RTX 4090
- RAM: 64 GB (2×32 GB DDR5-5800 C30)
- SSD: Solidigm P44 Pro 2 TB
- OS: Linux (Fedora 40)
Using an optimize=speed lto=full
editor build.
Time taken to format the string 1 million times from GDScript (as a standalone expression):
"%d FPS (%.2f mspf)" % [Engine.get_frames_per_second(), 1000.0 / Engine.get_frames_per_second()]
Before | After |
---|---|
1.009s | 0.679s |
Lol, if I had to debug an issue arising from |
Thanks! |
This prevents an allocation of a new string for every
+= char32_t
. The example string was rendered as a label every frame in GDScript:To validate the improvement, allocations were captured for a 5-second window. Note the number of allocations in the
sprintf
function of the following images.Before: 43,830 allocations
After
operator += (char32_t)
: 17,474 allocationsNote
60% reduction in allocations.
After
static const String
: 12,934Note
A further improvement was to use some
static const String
for common padding and sign characters, which reduced the allocations a further 26%Note
Total reduction in allocations for the 5-second window was 70%