使用以下代码:
#include <chrono>
#include <iostream>
#include <thread>
#include <string>
#include <array>
#include <algorithm>
volatile int answer;
const int size = 15;
std::array<std::array<int, size>, 0x100> fresh_data;
std::array<std::array<int, size>, 0x100> data;
void naive(int n) {
auto & a = data[n];
std::sort(a.begin(), a.end());
answer = a[size / 2];
}
void fancy(int n) {
auto & a = data[n];
std::partial_sort(a.begin(), a.begin() + (size / 2 + 1), a.end());
answer = a[size / 2 ];
}
void ghoul(int n) {
auto & a = data[n];
std::array<int, size / 2 + 1> temp;
std::partial_sort_copy(a.begin(), a.end(), temp.begin(), temp.end());
answer = temp[size / 2];
}
void nthel(int n) {
auto & a = data[n];
std::nth_element(a.begin(), a.begin() + size / 2, a.end());
answer = a[size / 2];
}
void gen_data() {
for (auto & a : fresh_data)
for (auto & b : a)
b = rand();
}
void regen_data() {
data = fresh_data;
}
template <typename T>
void test(T f, std::string n) {
regen_data();
auto a = std::chrono::high_resolution_clock::now();
for (auto i = 0; i < 10000; ++i)
for (auto i = 0; i < 0x100; ++i)
f(i);
auto b = std::chrono::high_resolution_clock::now();
std::cout << n << ": " << std::chrono::duration_cast<std::chrono::milliseconds>(b - a).count() << std::endl;
}
int main() {
gen_data();
test(naive, " std::sort");
test(fancy, " std::partial_sort");
test(ghoul, "std::partial_sort_copy");
test(nthel, " std::nth_element");
}
我得到了以下结果:
std::sort: 141
std::partial_sort: 359
std::partial_sort_copy: 831
std::nth_element: 149
在一台搭载AMD Phenom II x4 2.5GHz的计算机上,使用64位发布模式在Visual Studio 2013中进行了测试。
nth_element
的渐近复杂度是线性的,而另外两个则是线性对数的。第三,partial_sort_copy
需要分配内存并复制元素,因此可能会更慢。 - Siyuan Renpartial_sort_copy
把更多的内存投入到问题中,但这是一把双刃剑。如果你溢出了CPU缓存,一个更大的工作集会降低性能。 - Potatoswatter