定数回のループを高速化する with fold expression

久しぶりにネタになりそうなことが見つかったのだ!更新してないからか、読む人はめちゃめちゃ少ないのだけれど、ありがたいことに0人ではないので、せっかく見つかったネタを自分だけの知見とせずにアウトプットしたいと思う。

またC++の話だけれど、ライブラリを作っててちょっと高速化できた書き方を紹介するよ。

本題

forwhiledo-while goto いろいろあります 反復文。何を使ってもいいが静的に反復する回数が決まるならそれらは必要ないのだ!例えばforを書く。

constexpr int cnt = 10;
for(auto i = 0; i < cnt; ++i) { some_work(); }

上のように書いた時、cntが定数なのにiを一回ごとに1ずつ加算してcntと比較してi < cntならば最初に戻るという一連の動作をする。おかしい。どう考えても無駄だ。forの中身をそのまま10回書いた方がどう考えても速い。

some_work();
some_work();
some_work();
some_work();
some_work();

some_work();
some_work();
some_work();
some_work();
some_work();

まあだがこの書き方は誰が見てもバカなので、モダンで洗練されていてなんでも出来てかっこいいC++には似合わない。確かこういう時に使えそうな機能が…… ほら、あったじゃないか。C++17で追加されたモダンで洗練されていてかっこいいfold expressionが!!!!

template<size_t ...S>
void do_some_work(std::index_sequence<S...>) {
    ((S, some_work()), ...);
}
do_some_work(std::make_index_sequence<10>{});

速くてかっこいいC++にはこういう書き方が似合う*1

速くなるか半信半疑の人のためにwandboxへのリンクを貼っておく。

wandbox.org

*1:諸説あります