バイナリサーチは末尾再帰で書けるので、最適化できる。では、末尾再帰ではない再帰は、どのようなコードが生成されるのか。たとえば、クイックソートだ。
template < typename Iterator > void quick_sort(Iterator first, Iterator last) { if ( std::distance(first, last) < 3 ) { return ; } // 末尾 Iterator left(first), right(last) ; ++left ; --right ; while ( left < right ) { while ( left <= right && *left <= *first ) { ++left ; } while ( left <= right && *right > *first ) { --right ; } if (left < right ) { std::iter_swap(left, right) ; } } std::iter_swap(first, right) ; quick_sort(first, right) ; quick_sort(++right, last) ; //末尾 }
どうもスマートに書くのは難しいが、とりあえず実験の用には足りるだろう。これはどう見ても末尾再帰ではない。これをVC8でコンパイルしてみると、二つ目の再帰呼び出しは、最適化されてループになっていた。なるほど、そういうこともできるのか。
No comments:
Post a Comment