gpt4 book ai didi

c++ - isdigit() 在 C++ 中不应该更快吗?

转载 作者:行者123 更新时间:2023-11-30 02:41:09 25 4
gpt4 key购买 nike

我在 C++ 中使用 isdigit() 函数,但我发现它很慢,所以我实现了我自己的 is_digit(),请看下面我的代码:

#include<iostream>
#include<cctype>
#include<ctime>
using namespace std;
static inline bool is_digit(char c)
{
return c>='0'&&c<='9';
}
int main()
{
char c='8';
time_t t1=clock(),t2,t3;
for(int i=0;i<1e9;i++)
is_digit(c);
t2=clock();
for(int i=0;i<1e9;i++)
isdigit(c);
t3=clock();
cout<<"is_digit:"<<(t2-t1)/CLOCKS_PER_SEC<<"\nisdigit:"<<(t3-t2)/CLOCKS_PER_SEC<<endl;

return 0;
}

运行后,is_digit()只用了1秒(1161ms),而isdigit()却用了4秒(3674ms),我知道isdigit是位运算实现的,isdigit()不应该比is_digit()快吗?


更新1

我使用 MS VS2010 和默认选项,发布版本,如何使 isdigit() 比 VS 中的 is_digit() 更快?

更新2

谢谢大家。在 VS 中处于 Release模式时,项目将针对速度默认值(-O2)进行优化。

全部处于 Release模式。

VS2010:is_digit:1182(ms)isdigit:3724(ms)

VS2013:is_digit:0(ms)isdigit:3806(ms)

带有 g++(4.7.1) 和 -O3 的代码块:is_digit:1275(ms)isdigit:1331(ms)

结论是:

is_digit() 比 VS 中的 isdigit() 快,但比 g++ 中的 isdigit() 慢。

而且 g++ 中的 isdigit() 比 VS 中的 isdigit() 更快。

所以“VS 很烂”的性能?

最佳答案

在 clang/llvm [我选择的编译器] 中,isdigitis_digit将变成完全相同的代码,因为它针对特定的库调用进行了优化,将其转换为 ((unsigned)(c-48) < 10u) .

return c>='0' && c <='9';也变成了c-48 > 10通过优化(作为编译器执行的通用 if x >= N && x <= M -> x-N > (M-N) 转换)。

因此,理论上,这两个循环应该变成相同的代码(至少使用对 isdigit 进行此类优化的编译器 - 我不能说 MSVC 是否这样做,因为源代码不提供给一般公众)。我知道gcc有类似的优化库调用的代码,但是目前我的机器上没有gcc源码,懒得去查[以我的经验,会难一点无论如何阅读都比 llvm 代码好。

llvm 中的代码:

Value *LibCallSimplifier::optimizeIsDigit(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
FunctionType *FT = Callee->getFunctionType();
// We require integer(i32)
if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() ||
!FT->getParamType(0)->isIntegerTy(32))
return nullptr;

// isdigit(c) -> (c-'0') <u 10
Value *Op = CI->getArgOperand(0);
Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp");
Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit");
return B.CreateZExt(Op, CI->getType());
}

对于那些不熟悉 LLVM 代码的人:它首先检查函数调用是否具有正确的参数数量和参数类型。如果失败,它返回 NULL 以指示“我无法优化它”。否则,它会构建操作链来执行 if (c - '0' > 10)。使用无符号比较来处理“负”值[在无符号中是巨大的值]。

这样做会出错:

bool isdigit(int x)
{
return image_contains_finger(imagefiles[x]);
}

[但是用你自己的版本替换库函数通常会产生有趣的效果!]

关于c++ - isdigit() 在 C++ 中不应该更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28425292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com