空数组初始化的性能差异
Performance difference in empty array initialization
最近一直在做performance/memory优化,卡在空数组初始化中,使用泛型方法初始化空数组:
泛型空数组的代码实现class:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
因此,无论何时创建任何类型的空数组,它都被这样调用:
var emptyStringArray = EmptyArray<string>.Instance;
这样的空数组声明已经在代码库的很多地方做了。我很困惑使用时它的性能会有什么不同:
var emptyStringArray = new string[0];
我问过上面的代码作者,他已经回复了我:
Basically, all empty arrays are readonly, and are equal to one
another, which means that you can use the same instance (which will be
created lazily on demand during run-time)… That should reduce the
total number of allocations, reduce memory usage and GC pressure, and
should result in some improvement
仍然,我无法理解 EmptyArray
Instance
如何提高数组声明的性能。
使用以下方法的代码是否存在任何性能差异:
第一种方法:
var emptyStrArr = EmptyArray<string>.Instance;
var emptyFooArr = EmptyArray<Foo>.Instance;
var emptyBarArr = EmptyArray<Bar>.Instance;
第二种方法:
var emptyStrArr = new string[0];
var emptyFooArr = new Foo[0];
var emptyBarArr = new Bar[0];
在第一个代码中,static
构造函数只执行 once.So 你只是创建一个数组并一直使用它。在第二个代码中,您每次都创建一个数组实例。这就是区别。
你可以通过改变构造函数看得更清楚:
static EmptyArray()
{
Instance = new T[0];
Console.WriteLine("Array of "+ typeof(T) + " is created.");
}
var s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
var i = EmptyArray<int>.Instance;
i = EmptyArray<int>.Instance;
// output:
// Array of System.String is created.
// Array of System.Int32 is created.
这个:
var emptyStringArray = new string[0];
每次调用时创建一个空字符串数组的新实例,以及所有相关的内存分配开销,而这个:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
只创建空字符串数组的单个实例,无论您调用 Instance
字段多少次。
只是为了说明这如何提高性能和内存你可以试试这个
using System;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
var str = EmptyArray<string>.Instance;
var intTest = EmptyArray<int>.Instance;
var intTest1 = EmptyArray<int>.Instance;
var str1 = EmptyArray<string>.Instance;
Console.WriteLine(str.GetType());
Console.WriteLine(intTest.GetType());
if (ReferenceEquals(str,str1))
{
Console.WriteLine("References are equals");
}
if (ReferenceEquals(intTest,intTest1))
{
Console.WriteLine("References are equals");
}
}
}
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
}
您可以看到,即使是值类型也不需要其他分配,考虑到对象的分配和销毁会消耗时间和内存,您可以通过这样做来增强您的代码
最近一直在做performance/memory优化,卡在空数组初始化中,使用泛型方法初始化空数组:
泛型空数组的代码实现class:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
因此,无论何时创建任何类型的空数组,它都被这样调用:
var emptyStringArray = EmptyArray<string>.Instance;
这样的空数组声明已经在代码库的很多地方做了。我很困惑使用时它的性能会有什么不同:
var emptyStringArray = new string[0];
我问过上面的代码作者,他已经回复了我:
Basically, all empty arrays are readonly, and are equal to one another, which means that you can use the same instance (which will be created lazily on demand during run-time)… That should reduce the total number of allocations, reduce memory usage and GC pressure, and should result in some improvement
仍然,我无法理解 EmptyArray
Instance
如何提高数组声明的性能。
使用以下方法的代码是否存在任何性能差异:
第一种方法:
var emptyStrArr = EmptyArray<string>.Instance;
var emptyFooArr = EmptyArray<Foo>.Instance;
var emptyBarArr = EmptyArray<Bar>.Instance;
第二种方法:
var emptyStrArr = new string[0];
var emptyFooArr = new Foo[0];
var emptyBarArr = new Bar[0];
在第一个代码中,static
构造函数只执行 once.So 你只是创建一个数组并一直使用它。在第二个代码中,您每次都创建一个数组实例。这就是区别。
你可以通过改变构造函数看得更清楚:
static EmptyArray()
{
Instance = new T[0];
Console.WriteLine("Array of "+ typeof(T) + " is created.");
}
var s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
s = EmptyArray<string>.Instance;
var i = EmptyArray<int>.Instance;
i = EmptyArray<int>.Instance;
// output:
// Array of System.String is created.
// Array of System.Int32 is created.
这个:
var emptyStringArray = new string[0];
每次调用时创建一个空字符串数组的新实例,以及所有相关的内存分配开销,而这个:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
只创建空字符串数组的单个实例,无论您调用 Instance
字段多少次。
只是为了说明这如何提高性能和内存你可以试试这个
using System;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
var str = EmptyArray<string>.Instance;
var intTest = EmptyArray<int>.Instance;
var intTest1 = EmptyArray<int>.Instance;
var str1 = EmptyArray<string>.Instance;
Console.WriteLine(str.GetType());
Console.WriteLine(intTest.GetType());
if (ReferenceEquals(str,str1))
{
Console.WriteLine("References are equals");
}
if (ReferenceEquals(intTest,intTest1))
{
Console.WriteLine("References are equals");
}
}
}
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
}
您可以看到,即使是值类型也不需要其他分配,考虑到对象的分配和销毁会消耗时间和内存,您可以通过这样做来增强您的代码