初期化リストを使うにあたって、初心者が信じてしまうかもしれないと懸念される問題は、std::initializer_listは、通常の配列に比べて、遅いのではないかという迷信だ。規格によれば、std::initializer_listは、通常の配列をautomatic storage、もしくはstatic storage上に構築し、その配列へのポインターを格納するのと、何ら変わることはない。
例えば、以下のようなコードは、
void f() { for ( auto i : { 1, 2, 3 } ) { std::cout << i << std::endl ; } }
最終的に、以下のように置き換えることができる。
void f() { int a[3] = { 1, 2, 3 } ; int * iter = a ; int * last = a + 3 ; for ( ; iter != last ; ++iter ) { auto i = *iter ; std::cout << i << std::endl ; } }
もちろん、細部をどのように実装するかについては、実装により異なる。しかし、初期化リストの各要素を格納するオブジェクトは、automatic storageかstatic storage上に構築可能である。
これを考えれば、std::minとstd::maxを、initializer_listで実装するか、Variadic Templatesで実装するかというのは、パフォーマンスを考えて見れば、ささいな違いではないかと思う。
したがって、std::initializer_listのパフォーマンスを心配するのは、「static変数やローカル変数、関数の実引数や戻り値のオブジェクトは、実装によってどこかよく分からないストレージ上に構築されるので信用ならん」と言うのに等しい。
いや、メモリーじゃなくてストレージという言葉が出てくる時点で、こう考えることはあり得ないか。
No comments:
Post a Comment