string.Create
Span<T>
What is Span? Span is a value type that enables us to work and manage any type that represents a contiguous chunk of memory. Meaning, it provides type-safe access to a contiguous area of memory.
Span<T> is struct, it will NOT cause heap allocation. It's very useful for performance.
The difference between heap and stack.
\ | HEAP | STACK |
---|---|---|
Memory | Allocated in random block | Allocated in continuous block |
Allocate and Deallocate | Manually | Automatically |
Cost | More, access Slower | Less, access Faster |
Thread safe | Nope | Yes, it is |
Flexibility | Dynamic length, can be resized | Fixed-length |
Data structure | Hierarchical | Linear |
String.Create Code Demo
Creates a new string with a specific length and initializes it after creation by using the specified callback. said from docs.
In another words, String.Create will help us to operate a string in a fancy way.
Now, that's take an easy example. We'll generate a random string by using for loop, a very basic try out.
public class StringMethods
{
private char[] _charsPool = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890".ToCharArray();
private Random _rnd = new();
private const int N = 20;
public string NormalStringAddForLoop()
{
var ret = "";
for (int i = 0; i < N; i++)
{
ret += _charsPool[_rnd.Next(_charsPool.Length)];
}
return ret;
}
public string ForLoopWithStringBuilder()
{
var ret = new StringBuilder();
for (var i = 0; i < N; i++)
{
ret.Append(_charsPool, _rnd.Next(_charsPool.Length), 1);
}
return ret.ToString();
}
public string ForLoopWithStringBuilderInFixedLength()
{
var ret = new StringBuilder(N);
for (var i = 0; i < N; i++)
{
ret.Append(_charsPool, _rnd.Next(_charsPool.Length), 1);
}
return ret.ToString();
}
public string ForLoopWithStringCreate()
{
return string.Create(N, _charsPool, (ret, _) =>
{
for (var i = 0; i < N; i++)
{
ret[i] = _charsPool[_rnd.Next(_charsPool.Length)];
}
});
}
}
-
First, as the code said, NormalStringAddForLoop, a basic way to join string, piece by piece.
-
Next, ForLoopWithStringBuilder, a better way to join string with dynamic length StringBuilder, while in loop.
-
The next, ForLoopWithStringBuilderInFixedLength, using a fixed-length StringBuilder will be more effective than dynamic one.
-
Last one, ForLoopWithStringCreate, the way that will catch your eyes, a very effective way than others.
For the goal purpose, we will run some diagnostic by using BenchmarkDotNet to exam functions we created.
To measure the functions, the project need to compile on RELEASE mode.
dotnet run -c RELEASE
Here are results run from two different machines. Take a look at these beautiful magic numbers.
Intel Core i7-4500U CPU 1.80GHz (Haswell), 1 CPU, 4 logical and 2 physical cores, full-power worked
the complete result shown blow.
Intel Core i7-10875H CPU 2.30GHz, 1 CPU, 16 logical and 8 physical cores, worked under 70% performance, default profile
the complete result shown blow.
Legends
Mean : Arithmetic mean of all measurements
Allocated: Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
A higher performance machine will run more quickly than a lower one, and, the StringCreate method always had a greater performance, besides, the Allocated memory always has a very small size.
That told us one thing important, if possible, using StringCreate to deal with array of string (or any other objects), would let our app run in better performance.
Here is why.
Explain Why
Span<T>, in this case it was Span<string>
Span<string>
A String.Create will directly work with each part of its value, without creating new a new instance (one-word string, or char). About that, our application's performance could be enhanced, and wasted less memory usage.
Conclusion
Above all, we could use this powerful API to make:
-
A string that had known length, such as an Serial Order String
-
A string that would be generated as an Unique Id (maybe same as 1.)
-
A string that need to deal or formatted with each character
Choose correct way to make our works smarter.
Enjoy it.
Background image is from unsplash
References: