To build on @Enigmativity’s answer, here’s a proper benchmark using BenchmarkDotNet:
public class Benchmark
{
private const int N = 1000000;
[Benchmark]
public HashSet<int> EnumerableRange() => new HashSet<int>(Enumerable.Range(1, N + 1));
[Benchmark]
public HashSet<int> NoPreallocation()
{
var result = new HashSet<int>();
for (int n = 1; n < N + 1; n++)
{
result.Add(n);
}
return result;
}
[Benchmark]
public HashSet<int> Preallocation()
{
var result = new HashSet<int>(N);
for (int n = 1; n < N + 1; n++)
{
result.Add(n);
}
return result;
}
}
public class Program
{
public static void Main(string[] args)
{
BenchmarkRunner.Run(typeof(Program).Assembly);
}
}
With the results:
Method | Mean | Error | StdDev |
---|---|---|---|
EnumerableRange | 29.17 ms | 0.743 ms | 2.179 ms |
NoPreallocation | 23.96 ms | 0.471 ms | 0.775 ms |
Preallocation | 11.68 ms | 0.233 ms | 0.665 ms |
As we can see, using linq is a bit slower than not using linq (as expected), and pre-allocating saves a significant amount of time.
1
solved Create Hashset with a large number of elements (1M)