2

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:

  1. Make it static like so: private static readonly string[] A = { "a" ,"b", "c" }
  2. Define it inside the function as: string[] A = { "a", "b", "c" }

Which option is preferred? Is there a performance difference or other things to consider?

1
  • 3
    Perhaps refer to the array via IReadOnlyList<T>. As in static readonly IReadOnlyList<string> a = new [] { "a", "b", "c" }. Commented Apr 5, 2018 at 6:10

3 Answers 3

7

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

I will mostly access the elements via Index and won't use any other fancy Iteration like functions. To be honest in my use case performance should never be a problem, I was just curious if the compiler would optimize things.
1

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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.