【发布时间】:2016-12-22 00:49:07
【问题描述】:
每当我尝试比较两种竞争算法(使用 C++)的执行时间时,我都会使用 std::chrono,正如之前在这个问题中所建议的那样:Measuring execution time of a function in C++
但是,我总是注意到,被比较算法的执行顺序对执行时间有很大影响。它甚至经常改变哪个竞争算法被认为是最快的。例如,假设我有两个算法algo1 和algo2。
我的意思是下面的代码:
std::chrono::high_resolution_clock::time_point start0, start1;
std::chrono::high_resolution_clock::time_point end0, end1;
start1 = std::chrono::high_resolution_clock::now();
algo1();
end1 = std::chrono::high_resolution_clock::now();
start2 = std::chrono::high_resolution_clock::now();
algo2();
end2 = std::chrono::high_resolution_clock::now();
auto time_elapsed1 = std::chrono::duration_cast<std::chrono::nanoseconds>(end1 - start1).count();
auto time_elapsed2 = std::chrono::duration_cast<std::chrono::nanoseconds>(end2 - start2).count();
从下面的代码给出不同的结果:
std::chrono::high_resolution_clock::time_point start0, start1;
std::chrono::high_resolution_clock::time_point end0, end1;
start2 = std::chrono::high_resolution_clock::now();
algo2();
end2 = std::chrono::high_resolution_clock::now();
start1 = std::chrono::high_resolution_clock::now();
algo1();
end1 = std::chrono::high_resolution_clock::now();
auto time_elapsed1 = std::chrono::duration_cast<std::chrono::nanoseconds>(end1 - start1).count();
auto time_elapsed2 = std::chrono::duration_cast<std::chrono::nanoseconds>(end2 - start2).count();
对于我可能想要比较的几乎所有算法 1 和 2。
所以,我的问题有两个方面:1)为什么会这样,即为什么顺序很重要? 2) 有没有更好的方法来比较两种算法的执行时间,即如何进行更好、更准确的比较?
PS:当然,我总是在所有编译器优化的情况下进行测试。
【问题讨论】:
-
您需要多次运行算法并获得平均值。可以将影响后续运行的东西加载到缓存中。
-
您必须确保算法运行足够长的时间才能获得有意义的时间间隔。鉴于此,需要注意的是数据缓存。尝试连续运行每个 algo() 两次并对第二次运行计时。
-
我假设您的函数具有可观察到的副作用。否则它们可能会被完全优化掉。此外,@NathanOliver 所说的,将每个算法运行数千/百万次并获得平均值/平均值。基准测试非常困难;)
-
@JesperJuhl 可能是一个好的基准测试产生硬数字的原因。
标签: c++ algorithm profiling performance-testing