Reputation: 1066
Prenote: I know that there is no such thing as a const Array
I have an Array of Strings that are never changed in code and for now is only used in one function. I have two options to declare the Array:
private static readonly string[] A = { "a" ,"b", "c" }
string[] A = { "a", "b", "c" }
Which option is preferred? Is there a performance difference or other things to consider?
Upvotes: 2
Views: 3466
Reputation: 2654
Although the thread is a bit old, here is a technology update:
Something like
public static ReadOnlySpan<byte> myArray => new byte[] {1, 2, 3, 4};
Is not causing any heap allocation, and the result is immutable It's kind of a compiler secret, and of course a ReadOnlySpan is not as flexible as a heap allocated array.
Upvotes: 1
Reputation: 2113
In this case you can go with any case and don't care about performance. The first option will be a bit faster on big numbers. I have executed the following code (using initialization in the method, static readonly array and hashset) with 1 and 10 mln multiple times.
class Program
{
static void Main(string[] args)
{
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
for (int i = 0; i < 10_000_000; i++)
{
IsSafe("POST");
}
watch.Stop();
Console.WriteLine($"Execution Time: {watch.ElapsedMilliseconds} ms");
Console.ReadLine();
}
//static readonly HashSet<string> safeMethods = new HashSet<string>(new[] { "GET", "OPTIONS", "HEAD", "TRACE" });
static readonly string[] safeMethods = new[] { "GET", "OPTIONS", "HEAD", "TRACE" };
static bool IsSafe(string method)
{
//var safeMethods = new[] { "GET", "OPTIONS", "HEAD", "TRACE" };
return safeMethods.Contains(method, StringComparer.InvariantCultureIgnoreCase);
}
}
The results on 1mln for all 3 cases are about the same - about 300ms on my laptop.
On 10mln the results are:
static array - 3.9sec
method - 4.4sec
static hashset - 4.4sec
Upvotes: 0
Reputation: 1501163
There's definitely a performance hit for the second option - it would create a new array and initialize it on every method call.
If you're confident that you won't accidentally mutate the array, I'd go for the first option. If you want to make it clearer in your code that you're trying to create an effectively-immutable collection, you could use:
private static readonly IReadOnlyList<string> A = new string[] { "a" ,"b", "c" };
That won't actually make it immutable though - you'd have to be careful not to pass it to any other code that might cast it back to string[]
and mutate it.
For true immutability, you could use Array.AsReadOnly
:
private static readonly IReadOnlyList<string> A =
Array.AsReadOnly(new string[] { "a" ,"b", "c" });
Or of course you could use the immutable collections library.
(Note that operations via IReadOnlyList<string>
will be somewhat slower than operating directly on the array; whether or not that's significant in your application will depend on what you're doing.)
Upvotes: 7