HashSet Initialisation Speed in C#

Which one is faster?

1var hs = new HashSet<int>(_data);
1var hs = new HashSet<int>();
2foreach(int i in _data) {
3    hs.Add(i);
4}
1var hs = new HashSet<int>(_data.Length);
2foreach (int i in _data) {
3	hs.Add(i);
4}

My first thought was that option 1 is definitely faster - I’m passing entire dataset into HashSet so .NET should be efficient enough to figure that out. Testing it:

MethodLengthMeanErrorStdDevMinMaxMedianGen0Gen1Gen2Allocated
WithConstructor100000052.07 ms44.886 ms2.460 ms49.47 ms54.37 ms52.36 ms454.5455454.5455454.545517.74 MB
WithAddNoLength100000053.45 ms5.679 ms0.311 ms53.10 ms53.70 ms53.54 ms900.0000900.0000900.000041.12 MB
WithAddWithLength100000037.92 ms15.129 ms0.829 ms37.01 ms38.64 ms38.10 ms500.0000500.0000500.000017.74 MB

which means option #3 is faster! Passing data length into constructor makes sure we’ll have no memory reallocation, and then adding element one by one fills it up quicker.

Benchmark Code

 1#LINQPad optimize+
 2
 3void Main()
 4{
 5	Util.AutoScrollResults = true;
 6	BenchmarkRunner.Run<Enumeration>();
 7}
 8
 9[ShortRunJob]
10[MinColumn, MaxColumn, MeanColumn, MedianColumn]
11[MemoryDiagnoser]
12[MarkdownExporter]
13public class Enumeration
14{
15	[Params(1000000)]
16	public int Length;
17    
18    private int[] _data;
19    private static Random random = new Random();
20
21	[GlobalSetup]
22	public void Setup()
23	{
24        _data = Enumerable.Range(0, Length).Select(i => random.Next()).ToArray();
25	}
26
27
28	[Benchmark]
29	public void WithConstructor()
30	{
31        var hs = new HashSet<int>(_data);
32	}
33
34    [Benchmark]
35    public void WithAddNoLength() {
36        var hs = new HashSet<int>();
37        foreach(int i in _data) {
38            hs.Add(i);
39        }
40    }
41
42    [Benchmark]
43    public void WithAddWithLength() {
44        var hs = new HashSet<int>(_data.Length);
45        foreach (int i in _data) {
46            hs.Add(i);
47        }
48    }
49
50
51}

Have feedback or questions? Feel free to email me.