Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created April 21, 2018 06:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/841a614a501130700e1c21e55318aa11 to your computer and use it in GitHub Desktop.
Save ufcpp/841a614a501130700e1c21e55318aa11 to your computer and use it in GitHub Desktop.
new 制約の遅さ
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
[MemoryDiagnoser]
public class NewBenchmark
{
// 既定値ではなく、new T() で要素を初期化しながら配列生成
static T[] Array<T>(int n)
where T : new()
{
var array = new T[n];
for (int i = 0; i < array.Length; i++)
array[i] = new T(); // new() 制約のおかげで空のコンストラクターを呼べる
return array;
}
// 同じことを実行時型情報を使ってやる
static T[] ArrayWithActivator<T>(int n)
{
var array = new T[n];
for (int i = 0; i < array.Length; i++)
array[i] = Activator.CreateInstance<T>(); // 実行時型情報を使う
return array;
}
// 中で new T() するのをあきらめて、外から Func をもらう
static T[] Array<T>(int n, Func<T> generator)
{
var array = new T[n];
for (int i = 0; i < array.Length; i++)
array[i] = generator(); // 外からもらった generator を呼ぶ
return array;
}
// 参考までに、ジェネリックでないものと比較
static int[] ArrayInt(int n)
{
var array = new int[n];
for (int i = 0; i < array.Length; i++)
array[i] = 0; // 配列は元から0初期化されるから無駄処理なんだけども、比較用に
return array;
}
static A[] ArrayA(int n)
{
var array = new A[n];
for (int i = 0; i < array.Length; i++)
array[i] = new A();
return array;
}
class A { }
[Benchmark]
public void WithNewConstraint()
{
Array<int>(1000);
Array<A>(1000);
}
[Benchmark]
public void WithActivator()
{
ArrayWithActivator<int>(1000);
ArrayWithActivator<A>(1000);
}
[Benchmark]
public void WithGenerator()
{
Array(1000, () => 0);
Array(1000, () => new A());
}
[Benchmark]
public void NonGeneric()
{
ArrayInt(1000);
ArrayA(1000);
}
}
class Program
{
static void Main()
{
BenchmarkRunner.Run<NewBenchmark>();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment