空数组初始化的性能差异

时间:2015-05-06 08:44:18

标签: c# .net arrays performance clr

最近,我一直在进行性能/内存优化,并且已经停留在使用泛型方法初始化空数组的空数组初始化中:

通用空数组类的代码实现:

    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];

我已经问过上面的代码作者了,他回复了我:

  

基本上,所有空数组都是只读的,并且等于1   另一个,这意味着你可以使用相同的实例(将是   在运行期间按需创建懒惰... ...这应该减少   分配总数,减少内存使用和GC压力,以及   应该会有一些改善

但是,我无法理解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];

3 个答案:

答案 0 :(得分:1)

在第一个代码中,static构造函数只执行一次。所以你只是创建一个数组并一直使用它。在第二个代码中,您每次都在创建一个数组实例。这就是区别。

通过更改构造函数,您可以更清楚地看到它:

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.

答案 1 :(得分:0)

此:

var emptyStringArray = new string[0];

每次调用时都会创建一个空字符串数组的新实例,并带有所有相关的内存分配开销,而这个:

public static class EmptyArray<T>
    {
        public static readonly T[] Instance;

        static EmptyArray()
        {
            Instance = new T[0];
        }
    }

无论您调用Instance字段多少次,都只会创建空字符串数组的单个实例。

答案 2 :(得分:0)

首先说明一下如何提高性能和内存,你可以试试这个

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];
        }
    }
}

你可以看到,即使对于值类型也不需要其他分配,并且鉴于对象的分配和销毁,时间和内存消耗可以通过这样做来增强代码