两种C++实现统计7整除数对的性能基准测试
针对数对统计问题的解答
1. y += 6这类循环优化的性能表现
这种手动跳过无效迭代的优化,本质是直接减少了循环总次数——你只遍历满足(x+y)%7==0的y值,迭代量是原全遍历的1/7,理论上必然能提升性能。
它的收益确实会受编译器优化影响,但核心优势不会被抵消:
- 如果编译器能自动识别出模7的规律(比如通过循环变换、模式匹配),可能会自动生成类似优化代码,此时手动
y +=6和编译器优化后的全遍历版本差距会缩小; - 如果编译器没识别出这种规律,手动优化版本会比全遍历版本快很多,数据量越大,迭代次数差距带来的性能提升越明显。
你做的小范围和大范围基准测试应该能验证这一点:小范围下循环开销占比低,提升可能不显著;大范围下迭代次数的大幅减少会带来清晰的性能优势。
2. C++中更优的实现方式
最推荐的是余数计数法,时间复杂度从遍历的O(n*m)降到O(n+m),数据量越大优势越突出:
- 先统计两个集合中每个数模7的余数出现次数:
// 假设x、y为存储目标数值的容器(如vector<int>) int count_x[7] = {0}; for (int num : x) { count_x[num % 7]++; } int count_y[7] = {0}; for (int num : y) { count_y[num % 7]++; } - 根据余数互补规则计算符合条件的数对总数:
long long total = 0; total += (long long)count_x[0] * count_y[0]; // 余数0与0互补 total += (long long)count_x[1] * count_y[6]; // 余数1与6互补 total += (long long)count_x[2] * count_y[5]; // 余数2与5互补 total += (long long)count_x[3] * count_y[4]; // 余数3与4互补 total += (long long)count_x[4] * count_y[3]; // 余数4与3互补 total += (long long)count_x[5] * count_y[2]; // 余数5与2互补 total += (long long)count_x[6] * count_y[1]; // 余数6与1互补
这种方法的核心逻辑是:(x+y)%7==0等价于x%7 + y%7 ≡ 0 mod7,即y的余数必须是(7 - x%7)%7,只需把对应余数的计数相乘再累加,完全避免了嵌套循环的开销。
内容的提问来源于stack exchange,提问作者Chirag Jain
相关产品推荐
相关产品推荐

