Created
April 21, 2018 06:44
-
-
Save ufcpp/841a614a501130700e1c21e55318aa11 to your computer and use it in GitHub Desktop.
new 制約の遅さ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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