prenote:我知道没有const数组之类的东西
我有一系列字符串,这些字符串从未在代码中更改,目前仅在一个函数中使用。我有两个选项可以声明数组:
- 使其像这样静态:
private static readonly string[] A = { "a" ,"b", "c" }
- 将其定义为:
string[] A = { "a", "b", "c" }
首选哪个选项?是否有性能差异或其他要考虑的事情?
第二个选项肯定有一个性能命中 - 它将创建一个新数组并在每个方法调用上进行初始化。
如果您有信心不会意外地突变数组,我会选择第一个选项。如果您想在代码中更清楚地知道要创建一个有效的免疫集合,则可以使用:
private static readonly IReadOnlyList<string> A = new string[] { "a" ,"b", "c" };
实际上不会使它不可变的 - 您必须小心,不要将其传递给任何可能将其归还给string[]
并将其变异的代码。
对于真正的不变性,您可以使用Array.AsReadOnly
:
private static readonly IReadOnlyList<string> A =
Array.AsReadOnly(new string[] { "a" ,"b", "c" });
或当然可以使用不变的藏品库。
(请注意,通过IReadOnlyList<string>
的操作比直接在数组上操作的操作要慢;是否在您的应用程序中重要的是取决于您在做什么。(
在这种情况下,您可以使用任何情况,也不关心性能。第一个选项在大数字上会更快。我已经执行了以下代码(使用该方法中的初始化,静态ReadOnly Array和Hashset(使用1和10 mln多次执行。
。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);
}
}
所有3个情况的1MLN的结果大约相同 - 我的笔记本电脑上约300ms。
10mln的结果为:
static array - 3.9sec
method - 4.4sec
static hashset - 4.4sec