Reputation:
Recently, I've been working in performance/memory optimization and have stucked in the empty array initialization which uses generic method to initialize empty array:
Code implementation of generic empty array class:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
So, whenever creating empty array of any type,it has been called as like:
var emptyStringArray = EmptyArray<string>.Instance;
Such empty array declaration has been done in many places of codebase. I am confused how would it be differs in performance while using :
var emptyStringArray = new string[0];
I've asked to above code author and he has replied me :
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
Still, I am not able to understand how would EmptyArray
Instance
boost the performance in array declaration.
Is there any performance difference in code using following approach :
1st Approach :
var emptyStrArr = EmptyArray<string>.Instance;
var emptyFooArr = EmptyArray<Foo>.Instance;
var emptyBarArr = EmptyArray<Bar>.Instance;
2nd Approach :
var emptyStrArr = new string[0];
var emptyFooArr = new Foo[0];
var emptyBarArr = new Bar[0];
Upvotes: 2
Views: 1810
Reputation: 13765
jus to illustrate a bit how this can boost performance and memory you can try this
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];
}
}
}
you can see that no other allocation is needed even for value type and given that allocation and destruction of objects it's time and memory consuming you can enhance your code by doing this
Upvotes: 0
Reputation: 101701
In the first code the static
constructor is executed only once.So you are just creating one array and using it all the time. In the second code you are creating an array instance each time. That's the difference.
You can see it more cleary by changing the constructor:
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.
Upvotes: 1
Reputation: 42032
This:
var emptyStringArray = new string[0];
Creates a new instance of an empty string array every time its called, with all the associated memory allocation overhead, whereas this:
public static class EmptyArray<T>
{
public static readonly T[] Instance;
static EmptyArray()
{
Instance = new T[0];
}
}
Only ever creates a single instance of the empty string array, regardless of how many times you call the Instance
field.
Upvotes: 0