我在查看<algorithm>
实现时找到了这个代码段:
/**
* @if maint
* This is an overload used by find() for the RAI case.
* @endif
*/
template<typename _RandomAccessIterator, typename _Tp>
_RandomAccessIterator
find(_RandomAccessIterator __first, _RandomAccessIterator __last,
const _Tp& __val, random_access_iterator_tag)
{
typename iterator_traits<_RandomAccessIterator>::difference_type
__trip_count = (__last - __first) >> 2;
for ( ; __trip_count > 0 ; --__trip_count)
{
if (*__first == __val)
return __first;
++__first;
if (*__first == __val)
return __first;
++__first;
if (*__first == __val)
return __first;
++__first;
if (*__first == __val)
return __first;
++__first;
}
switch (__last - __first)
{
case 3:
if (*__first == __val)
return __first;
++__first;
case 2:
if (*__first == __val)
return __first;
++__first;
case 1:
if (*__first == __val)
return __first;
++__first;
case 0:
default:
return __last;
}
}
根据我的理解,此处唯一的“技巧”是使用distance / 4
执行if(...) return; ++
次迭代,并使用distance % 4
内的其余switch
次项进行迭代。正如预期的那样,执行完全相同数量的比较和增量,并且理论复杂性是相同的。它是如何比简单的输入迭代器实现更好的优化?它是一种微优化,可以降低循环迭代的次数,还是有更聪明的东西我没有得到?
答案 0 :(得分:3)
这种技术称为loop unrolling,以避免在每次迭代时通过权衡二进制大小(和空间)来检查条件的成本。
加速也取决于你的体系结构,但通常super-scalar cpu可以通过打破可能在缓存丢失时阻止你的cpu的潜在危险的依赖链来利用它。
虽然理论复杂度是相同的(如果你考虑比较主导操作),算法(在我描述的cpu上)可以显着更快地执行。就复杂性约束而言,任何STL库都可以实现自己的版本。