【D言語】enumを使った配列のコンパイル時定数は遅い?
D言語erの皆さん、こんにちは。
今回は、enumを使った配列のコンパイル時定数の読み取り速度について書いていきます。
試してみる
実際に計測してみます。 今回は、enumとconstとimmutableのコンパイル時定数と、実行時の値で、速度を比べてました。
コード
import std.datetime, std.stdio, std.algorithm, std.math;
enum ary1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60];
static assert(ary1[0] == 0);
const ary2 = ary1;
static assert(ary2[0] == 0);
immutable ary3 = ary1;
static assert(ary3[0] == 0);
void main(){
auto ary4 = ary1;
auto res = benchmark!({ auto a = ary1.map!log2; }, { auto a = ary2.map!log2; }, { auto a = ary3.map!log2; }, { auto a = ary4.map!log2; })(10_000);
res.writeln;
}
実行結果
感想
enumだけ、桁違いに遅いですね。不思議です。
なぜか?
気になったので、Twitterで聞いてみました。
D言語のコンパイル時定数の読み取り速度(?)を比較してみたけど、どうしてenumだけこんなに遅いんだろう? -release -O -inlineつければ変わるかな? dpaste.dzfl.pl/44ff0fe9 #dlang
— Codelogyさん (@codelogy) 10月 6, 2012
すると、Phobosコミッターとして有名なrepeatedlyさんから、
@codelogy enumはシンボルがランタイム時には存在しないので,enumで大きなオブジェクトを作ると,それを参照している所で毎回構築することになって遅い.
— Mr. Fiberさん (@repeatedly) 10月 6, 2012
という返信が来ました。
結論
enumを使って配列を定数にすると、毎回その配列が作られることになり遅くなるみたいです。
よって、配列をコンパイル時定数にするときは、enumを使わずにconstなどを使うといいのでしょう。
皆さんも、enumでコンパイル時定数を作ると、とても読み取り速度が遅くなるので、気をつけてください。
担当:美馬(constとimmutableの違いについての記事にツッコミがあって嬉しい)