【发布时间】:2020-12-03 01:09:08
【问题描述】:
我的代码遇到了瓶颈,所以这个问题的主要问题是性能。
我有一个十六进制校验和,我想检查一个字符数组的前导零。这就是我正在做的:
bool starts_with (char* cksum_hex, int n_zero) {
bool flag {true};
for (int i=0; i<n_zero; ++i)
flag &= (cksum_hex[i]=='0');
return flag;
}
如果cksum_hex 有n_zero 前导零,则上述函数返回true。但是,对于我的应用程序,此功能非常昂贵(占总时间的 60%)。换句话说,它是我的代码的瓶颈。所以我需要改进它。
我还检查了 C++20 中可用的 std::string::starts_with,我发现性能没有差异:
// I have to convert cksum to string
std::string cksum_hex_s (cksum_hex);
cksum_hex_s.starts_with("000"); // checking for 3 leading zeros
有关更多信息,我正在使用g++ -O3 -std=c++2a,我的 gcc 版本是 9.3.1。
问题
- 检查 char 数组中的前导字符的更快方法是什么?
-
std::string::starts_with有没有更有效的方法? - 按位运算在这里有用吗?
【问题讨论】:
-
@GuillaumeGris 我确信 n_zero 永远不会超过 cksum_hex 的范围。我们在编译时不知道 n_zero。
-
这是一个非常微不足道的函数,很难想象一个程序会占用 60% 的时间,除非
n_zero通常非常高。函数是内联的吗?我想不会,因为内联函数通常不会出现在分析器上。内联可能是最大的胜利。此外,有两种类型的分析器,仪器分析器和采样分析器。检测分析器通常会增加每个函数调用的开销,这会夸大频繁调用函数的重要性。 -
可能是一个愚蠢的问题,但你为什么使用“&=”运算符?如果一发现非零数字就返回 false,难道不是更简单、检查更少吗?
-
对于那些想知道为什么按位运算可能是个好主意的人,它允许编译器进行一些向量化,因为它可以“知道”
n_zero。字符将被读取。想象一下n_zero == 4,然后所有这个函数都被“加载一个未对齐的 int 并检查它的值是否为零”而不是四个比较替换。编译器不能用逻辑和来做到这一点 -
你能像 SSE2 一样使用 x86 SIMD 吗?
标签: c++ performance optimization c++20