【问题标题】:Comparing algorithms' execution time: why does the order of execution matter?比较算法的执行时间:为什么执行顺序很重要?
【发布时间】:2016-12-22 00:49:07
【问题描述】:

每当我尝试比较两种竞争算法(使用 C++)的执行时间时,我都会使用 std::chrono,正如之前在这个问题中所建议的那样:Measuring execution time of a function in C++

但是,我总是注意到,被比较算法的执行顺序对执行时间有很大影响。它甚至经常改变哪个竞争算法被认为是最快的。例如,假设我有两个算法algo1algo2

我的意思是下面的代码:

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


【解决方案1】:

这很可能是由于缓存造成的。

您可以通过多次运行 SAME 算法轻松验证缓存的效果。您可能会注意到,第一次执行所花费的时间比后续执行要长得多。

当我不得不为我的博士论文比较两种算法时,我最终连续执行每种算法 10 次,丢弃了第一个结果,然后对剩余的 9 个结果取平均值,这 9 个结果非常一致。

第一个被丢弃的结果是否重要值得商榷,但对我来说并不重要,因为我更感兴趣的是比较两种算法的相对性能(因此寻找每个算法的一致运行时间)算法),而不是衡量缓存的影响或每种算法在不同情况下的绝对性能。

【讨论】:

  • 对我来说诀窍正是您的建议:不仅多次运行算法,而且丢弃初始值。更准确 - 可以针对任何事先知道实际解决方案的分析问题进行验证。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多