我有一个看起来像这样的功能(只显示重要部分):
double CompareShifted(const std::vector<uint16_t>& l, const std::vector<uint16_t> &curr, int shift, int shiftY) {
...
for(std::size_t i=std::max(0,-shift);i<max;i++) {
if ((curr[i] < 479) && (l[i + shift] < 479)) {
nontopOverlap++;
}
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
写得这样,我的机器上的功能耗时约34ms.将条件更改为bool乘法后(使代码看起来像这样):
double CompareShifted(const std::vector<uint16_t>& l, const std::vector<uint16_t> &curr, int shift, int shiftY) {
...
for(std::size_t i=std::max(0,-shift);i<max;i++) {
if ((curr[i] < 479) * (l[i + shift] < 479)) {
nontopOverlap++;
}
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
执行时间减少到~19ms.
使用的编译器是带有-O3的GCC 5.4.0,在使用godbolt.org检查生成的asm代码后,我发现第一个示例生成跳转,而第二个示例没有生成跳转.我决定尝试GCC 6.2.0,它在使用第一个例子时也生成一个跳转指令,但GCC 7似乎不再生成一个.
找到这种加速代码的方式是相当可怕的,花了很长时间.为什么编译器会以这种方式运行?这是程序员应该注意的吗?还有更类似的东西吗?
编辑:链接到godbolt https://godbolt.org/g/5lKPF3
我在使用std :: copy时遇到了一些奇怪的行为.同
std::vector<std::string> chosenIDs{...};
for (const auto& x : chosenIDs) {
std::string strID("");
std::copy(std::begin(x), std::find(std::begin(x), std::end(x), '.'), std::begin(strID));
std::cout << strID << "\n";
}
Run Code Online (Sandbox Code Playgroud)
但是,strID字符串包含它不应该使用的字符
std::vector<std::string> chosenIDs{...};
for (const auto& x : chosenIDs) {
std::string strID(std::begin(x), std::find(std::begin(x), std::end(x), '.'));
std::cout << strID << "\n";
}
Run Code Online (Sandbox Code Playgroud)
工作得很好.我很清楚我应该使用第二种方法,但它仍然让我感到困惑的是为什么第一个片段中的行为与第二个片段的行为不同.
我正在使用GCC 5.4.0