バイナリサーチは末尾再帰で書けるので、最適化できる。では、末尾再帰ではない再帰は、どのようなコードが生成されるのか。たとえば、クイックソートだ。
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