按位 XOR 与求和之间的性能差异似乎不存在
Performance difference between bitwise XOR vs summations seems off
我最近看到了一个很好的编程问题解决方案。给定 2 个列表,在其中一个列表中找到缺少的数字。
我最初的解决方案是这样的:
long long missing_2(long long a[], long long b[], long long bsize) {
long long asum = a[bsize], bsum = 0;
for (long long i = 0; i < bsize; i++) {
asum += a[i];
bsum += b[i];
}
return asum-bsum;
}
但是有人建议这样的事情:
long long missing_3(long long a[], long long b[], long long bsize) {
long long sum = 0 ^ a[bsize];
for (long long i = 0; i < bsize; i++) {
sum ^= a[i];
sum ^= b[i];
}
return sum;
}
出于好奇,我定时了 2 个解决方案,认为第二个解决方案missing_3
会更快。我得到了这些结果
missing_2:所需时间:16.21秒
missing_3:所用时间:23.39秒
列表是使用 for 循环生成的。列表 b 填充整数0-1000000000
,列表 a 填充 1-1000000000,末尾附加一个随机数(因此它包含 1 个不同的(额外)值。
问题按位版本需要 23.39 秒,求和版本需要 16.21 秒。知道为什么按位版本会明显比求和版本慢吗?我本以为按位运算会比加法或至少类似运算更快。
编辑:
使用没有额外标志/选项的g++
编译。
编辑2:
用-O1
和-O2
的标志进行测试,没有明显的区别。
编辑3:
这是驱动程序代码:
long long smaller_size = 1000000000;
long long* a = new long long[smaller_size+1];
long long* b = new long long[smaller_size];
for(long long i = 0; i < smaller_size; i++){
a[i] = b[i] = i;
}
a[smaller_size] = 1434;
// std::cout << missing_1(a, b, smaller_size) << std::endl;
clock_t tStart = clock();
std::cout << "Start List Testn";
std::cout << missing_2(a, b, smaller_size) << std::endl;
printf("Time taken: %.2fsn", (double)(clock() - tStart)/CLOCKS_PER_SEC);
tStart = clock();
std::cout << missing_3(a, b, smaller_size) << std::endl;
printf("Time taken: %.2fsn", (double)(clock() - tStart)/CLOCKS_PER_SEC);
编辑 5:时间部分更新(无时间更改)
clock_t tStart = clock();
std::cout << "Start List Testn";
double time;
missing_2(a, b, smaller_size);
time = (double)(clock() - tStart)/CLOCKS_PER_SEC;
printf("Time taken: %.2fsn", time);
tStart = clock();
missing_3(a, b, smaller_size);
time = (double)(clock() - tStart)/CLOCKS_PER_SEC;
printf("Time taken: %.2fsn", time);
正如彼得和马特奥在问题评论中提到的。
尽管 XOR 对于单个操作与加法是相等/更快的。由于流水线,XOR 版本比求和版本慢。
一个 XOR 必须等待前一个 XOR 操作完成才能开始其操作,而求和(加法)可以并行运行,因此使用流水线。反过来,允许求和比按位 XOR 更快结束。
这个答案的灵感来自彼得斯的评论。我只是想确保这个问题有一个可用的答案,彼得选择不写一个。
编辑:
多亏了 phuclv,更改代码以对数组a
求和并单独b
(请参阅下面的注释)会破坏依赖关系并导致 XOR 返回比求和更快/相等。
相关文章:
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- g++ 说函数不存在,即使包含正确的标头
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- C++ 尝试在不存在的构造函数中引用已删除的函数(使用 rapidJson)
- 查找第一个数组中不存在的元素
- 查找不存在的键时,unordered_map返回什么
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- set::find 查找不存在的元素
- 有没有办法将字符串添加到 Vector 中,但前提是它尚不存在?->C++
- inet_ntop返回不存在的地址
- CPP 使用不存在的键访问映射
- 为什么QMediaGaplessPlaybackControl不存在?
- 如果键不存在,使用 [] 运算符访问 STL Map 元素会添加新元素
- 标记未定义的颜色,并且颜色匹配系统中不存在样品
- 为什么使用默认构造函数"{}"而不是"= default"存在性能变化?
- 为什么minhook库目录不存在
- 为什么 std::vector::p ush_front() 不存在?
- 不存在从"Magick::Color"到"MagickCore::Quantum"的合适转换功能
- 按位 XOR 与求和之间的性能差异似乎不存在