我可以依靠我的编译器来优化const char*上的strlen吗?

Jac*_*cko 15 c compiler-construction optimization llvm strlen

在我的SAX xml解析回调(XCode 4,LLVM)中,我正在对这种类型的代码进行大量调用:

static const char* kFoo = "Bar";

void SaxCallBack(char* sax_string,.....)
{
     if ( strcmp(sax_string, kFoo, strlen(kFoo) ) == 0)
     {

     }


  }
Run Code Online (Sandbox Code Playgroud)

假设strlen(kFoo)由编译器优化是否安全?

(Apple示例代码已经预先计算了strlen(kFoo),但我认为这对于大量常量字符串很容易出错.)

编辑:优化的动机:使用NSXMLParser在iPod touch 2G上解析我的SVG地图需要5秒钟(!).所以,我想切换到lib2xml,并优化字符串比较.

R..*_*R.. 11

不要写像:

static const char* kFoo = "Bar";
Run Code Online (Sandbox Code Playgroud)

您已经创建了一个名为指向常量数据的变量kFoo.编译器可能能够检测到此变量不会更改并优化它,但如果没有,则会使程序的数据段膨胀.

也不要写像:

static const char *const kFoo = "Bar";
Run Code Online (Sandbox Code Playgroud)

现在你的变量kFooconst限定的和不可修改的,但是如果它在位置无关的代码(共享库等)中使用,那么内容在运行时仍然会有所不同,因此会增加程序的启动和内存成本.相反,使用:

static const char kFoo[] = "Bar";
Run Code Online (Sandbox Code Playgroud)

甚至:

#define kFoo "Bar"
Run Code Online (Sandbox Code Playgroud)

  • 我不推荐C++中的`#define`选项,绝对不行!感谢指点问题. (7认同)
  • `static const char*`的问题是你在数据段中创建一个实际变量,其*contents*是另一个静态存储持续时间对象(字符串文字)的地址.此值因加载地址而异,因此必须在加载时进行修补(通过重定位).使用`static const char []`,地址不驻留在任何静态存储持续时间对象中,引用该数组的代码可以通过在链接时固定的与位置无关的干净PC相对地址访问它. (7认同)
  • @R ..据我所知,另一方面声明一个数组至少会导致GCC实际上复制堆栈上的整个文字,块大块.在这种情况下,必须权衡是否要支付代码修补或堆栈分配的代价.我对吗? (2认同)
  • @amn:如果我们谈论具有自动存储持续时间的对象,你会是对的,但这些对象具有静态存储持续时间. (2认同)

Pas*_*uoq 10

如果通过"LLVM"你的意思是铿锵,那么是的,你可以指望clang -O优化strlen离开.以下是函数的代码:

_SaxCallBack:
Leh_func_begin1:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    leaq    L_.str1(%rip), %rsi
    movl    $3, %edx
    callq   _strncmp
    ...
Run Code Online (Sandbox Code Playgroud)

我改变了strcmpstrncmp,但第三个参数确实已经被眼前所取代$3.

请注意,gcc 4.2.1 -O3不会优化此strlen调用,并且您只能期望它在您的问题的精确条件下工作(尤其是字符串和调用strlen必须在同一个文件中).

  • 如果`kFoo`本身是`const`(即``static const char*const kFoo ="Bar";`),gcc会优化`strlen()`. (2认同)