我用3种不同的方式在C ++中实现了Insertion Sort。一个使用基本的C数组,一个使用向量,一个使用迭代器:
void insertionsort_array(int *arr, size_t length)
{
for (int i = 1; i < length; i++)
for (int k = i; k > 0 && arr[k] < arr[k-1]; k--)
swap(arr[k], arr[k-1]);
}
template<typename T>
void insertionsort_vector(vector<T>& arr)
{
for (int i = 1; i < arr.size(); i++)
for (int k = i; k > 0 && arr[k] < arr[k-1]; k--)
swap(arr[k], arr[k-1]);
}
template<class IterType>
void insertionsort_iterator(IterType iter, IterType end)
{
for (IterType edge = iter + 1; edge != end; ++edge)
for (IterType ptr = edge; ptr != iter && *ptr < *(ptr-1); --ptr)
swap(*ptr, *(ptr-1));
}
我希望这些函数的运行时间会有所不同。然而,情况并非如此(与GCC -O0的时间安排):
// array
Sorting 1000000 lists of length 10: 2605531 usec
Sorting 50000 lists of length 100: 1268442 usec
Sorting 500 lists of length 1000: 787731 usec
Sorting 5 lists of length 10000: 759133 usec
// vector
Sorting 1000000 lists of length 10: 2888354 usec
Sorting 50000 lists of length 100: 2031675 usec
Sorting 500 lists of length 1000: 1604312 usec
Sorting 5 lists of length 10000: 1603279 usec
// iterator
Sorting 1000000 lists of length 10: 3003877 usec
Sorting 50000 lists of length 100: 4150561 usec
Sorting 500 lists of length 1000: 3829943 usec
Sorting 5 lists of length 10000: 3766683 usec
对于长度为10的列表,它们都具有大致相同的性能,但对于长度为10的数组,迭代器几乎比C数组差五倍。怎么会这样?
编辑:我使用-O3重新测试它,效果似乎消失了。很高兴知道我可以使用编译器优化来避免这个问题,但我仍然想了解在-O0发生的这种奇怪的行为。
// array
Sorting 1000000 lists of length 10: 802136 usec
Sorting 50000 lists of length 100: 300472 usec
Sorting 500 lists of length 1000: 185330 usec
Sorting 5 lists of length 10000: 179851 usec
// vector
Sorting 1000000 lists of length 10: 955003 usec
Sorting 50000 lists of length 100: 302232 usec
Sorting 500 lists of length 1000: 185034 usec
Sorting 5 lists of length 10000: 181459 usec
// iterator
Sorting 1000000 lists of length 10: 811077 usec
Sorting 50000 lists of length 100: 230852 usec
Sorting 500 lists of length 1000: 112885 usec
Sorting 5 lists of length 10000: 105739 usec
我使用-O0或-O3在GCC中编译,并且没有使用其他编译器标志。
答案 0 :(得分:4)
没有优化,最大的区别可能来自调用operator[]
等函数。当函数调用there is a lot that happens时会导致开销,并且在循环中调用时尤为重要。但是,启用优化后,所有这些函数调用都是inlined,这就是您看到差异消失的原因。请注意,现在任何编译器都应该为您提供几乎相同的性能,无论您使用的是std::vector
还是普通数组。