我有100个double
值的集合,必须多次用修复int
变量除以:
unsigned int current_interval = double_value / int_value;
我需要知道以下简单缓存是否会更便宜(以及为什么?):
std::map<double_value,current_interval> cache;
//...
unsigned int get_interval(double_value / int_value){
if((it = cache.find(double_value)) != cache.end()
{
return it->second;
}
unsigned int current_interval = double_value / int_value;
cache[double_value] = current_interval;
return current_interval;
}
谢谢
答案 0 :(得分:2)
摘要:执行重复分割可能比在地图中查找值更快
<强>详细信息:强>
我认为这是一个有趣的问题。至少从与浮点除法相比的地图查找的执行时间的角度来看。在解决这个问题之前,我想重申其中两条评论:
1)如果你真的只有100个双打,你除以一个固定的值,然后使用很多次,我希望你应该能够转换你的算法直接使用这个结果。我希望这比提出的缓存算法更有效。
2)不要在地图中使用double
作为关键字。
现在谈谈主要问题。为了回答这个问题,我写了两个小程序。第一个只是在大小为100的地图中查找值。第二个执行浮点除法。我已经包含了完整的源代码,以防有人想要复制我的结果。另外对于第二个程序,我只是为了保持相同的结构而包含一些额外的代码,但是在第二个循环中重要的是。
<强> map.cpp 强>
#include <map>
#include <stdlib.h>
std::map<int,int> testmap;
int main(int argc, char **argv) {
int count = atoi(argv[1]);
int val = atoi(argv[2]);
int total = 0;
for(int i = 0; i < 100; i++) {
testmap[i] = val + i;
}
for(int i = 0; i < count; i++) {
for(int j = 0; j < 100; j++) {
total += testmap[j];
}
}
return total;
}
<强> double.cpp 强>
#include <map>
#include <stdlib.h>
std::map<int,int> testmap;
int main(int argc, char **argv) {
int count = atoi(argv[1]);
double val = atof(argv[2]);
double total = 0;
for(int i = 0; i < 100; i++) {
testmap[i] = val + i;
}
for(int i = 0; i < count; i++) {
for(int j = 0; j < 100; j++) {
total += val / j;
}
}
return total;
}
我用O1和O3编译,以确保编译器没有优化循环。我还测试了一些不同的迭代大小,以确保执行时间与迭代计数一致。
我在使用Intel(R) Xeon(R) CPU E3-1275 v3 @ 3.50GHz
g++ (GCC) 4.9.2
系统上运行了测试
对于O1,运行10000000次迭代的结果是:
map: 7.1 seconds
double: 3.6 seconds
对于O3,我的结果是:
map: 5.3 seconds
double: 3.5 seconds
所以区别并不大,但很明显,我在这里写的小微基准测试中,划分实现速度更快。而且实施起来也更简单。因此,我认为尝试记住除法结果,然后在地图中查找它们的可能性要小于在需要时简单计算值的速度。为了使memoization有用,基本操作需要比现代CPU中大量优化的浮点除法更昂贵。