✅ How to create char[] faster?
I have following class:
cs
I don't understand why but second version is a little bit slower:
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|----------------- |---------:|--------:|--------:|-------:|----------:|
| StartGeneration1 | 174.6 ns | 3.41 ns | 3.65 ns | 0.0143 | 136 B |
| StartGeneration2 | 170.3 ns | 3.36 ns | 6.47 ns | 0.0143 | 136 B |
why? is it possible to create char[] without allocating memory?
33 Replies
the results say the second version is faster?
and you can't allocate an array without allocating memory
the array itself is the allocation
The results say absolutely nothing
You're within margin of error in either scenario
i guess they're within error yeah
but 174 > 170 so StartGeneration1 is slower
No
It's 174 + or - 3.4, and 170 + or - 3.36
When you look at your error, you need to consider whether there's any overlap
In this case, you overlap between 171 (min for result 1) and 173 (max for result 2)
Because there's this overlap, you can draw no conclusions from this test
Run it again and you may get the exact opposite result
I wanted to create random string as fast as possible so I decided to use stackalloc but maybe it is wrong
And, frankly, I wouldn't expect there to be any statistically significant speed difference between these tests
So that result is exactly what I would have expected you to get
You are nearly certainly prematurely optimizing here
it's probably faster if you get all the bytes and then cast to int or whatever
that's assuming this was just for fun
you wouldn't do that in actual code unless it's insanely performance critical
it is only for fun
if you want a string, then you should use string.Create
sumpin like that
there's also this method in net8 you could try https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator.getstring?view=net-8.0
RandomNumberGenerator.GetString(ReadOnlySpan, Int32) Method (System...
Creates a string populated with characters chosen at random from choices.
didn't know about that, thanks
by the way! I found the fastest solution, one moment
third one is the fastest
that doesn't work
the third one returns a pointer to free'd memory
ah..
it was allocated in that method's stack frame, and that method's stack frame is gone after you return
I would also love to see what output you got from the benchmark
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|----------------- |---------:|--------:|--------:|-------:|----------:|
| StartGeneration1 | 172.0 ns | 1.60 ns | 1.42 ns | 0.0143 | 136 B |
| StartGeneration2 | 170.9 ns | 3.39 ns | 5.48 ns | 0.0143 | 136 B |
| StartGeneration3 | 164.5 ns | 3.11 ns | 3.05 ns | 0.0076 | 72 B |
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen0 : GC Generation 0 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 ns : 1 Nanosecond (0.000000001 sec)
Gotcha. Still not statistically signficiant
almost all the time here is spent doing Random.Next
not in how you make and return the array
Max of 3 is 167.61, min of 2 is 167.51
(There's also that point)
(And also the fact that 3 returns a dangling pointer to invalid memory)
hm ok we found a bottleneck! I will rewrite rnd.next
You won't get faster
I applaud the spirit of learning, but I really don't think this is it
You can get a good bit faster
Something like that
Probably better ways out there
I assume they want a valid ascii char
hm I thinked about this:
and then
and random is RandomNumberGenerator maybe
I will test this
I believe RandomNumberGenerator is slower than Random is
since it's cryptographic randomness instead of a prng
but maybe second one is wrong, I will test the output
works fine
thanks guys
@ivefifthsence use string.Create
how can i learn to be smart like you
Work hard
The second one introduces a slight bias toward earlier letters of the alphabet. For example, A will appear in the output more than Z, and this will be statistically significant.