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

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

static const char* kFoo = "Bar"; void SaxCallBack(char* sax_string,.....) { if ( strcmp(sax_string, kFoo, strlen(kFoo) ) == 0) { } } 

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

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

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

如果通过“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 ... 

我将strcmp更改为strncmp ,但第三个参数确实被直接的$3取代。

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

不要写像这样的东西:

 static const char* kFoo = "Bar"; 

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

也不要写像:

 static const char *const kFoo = "Bar"; 

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

 static const char kFoo[] = "Bar"; 

甚至:

 #define kFoo "Bar" 

一般来说,你不能指望它。 但是,您可以使用’sizeof’并将其应用于字符串文字。 当然,这意味着您不能像最初定义的那样定义’kFoo’。

以下内容适用于所有编译器和所有优化级别。

 #define kFoo "..." ... strcmp(... sizeof(kFoo)) 

后续问题:

你测试过以下的吗?

 static std::string const kFoo = "BAR"; void SaxCallBack(char* sax_string,.....) { if ( sax_string == kFoo) { } } 

这是可读性的净赢,但我不知道性能成本。

作为替代方案,如果您必须自己发送,我发现使用类似状态机的方法(使用堆栈)可读性更好,并且也可能在性能方面获胜(而不是使用大量标签)开启你只有现在可以满足的标签)。