在我的 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) 已被编译器优化吗?
(苹果示例代码 已经预先计算了 strlen(kFoo),但我认为这对于大量常量字符串来说很容易出错。)
编辑:优化动机:使用 NSXMLParser 在 iPod touch 2G 上解析我的 SVG 地图需要 5 秒(!)。所以,我想切换到lib2xml,并优化字符串比较。
如果“LLVM”指的是 clang,那么是的,您可以依靠
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";
现在你的变量
kFoo
是 const
限定且不可修改的,但如果它在位置无关代码(共享库等)中使用,内容在运行时仍然会有所不同,因此会增加启动和内存成本你的程序。相反,使用:
static const char kFoo[] = "Bar";
甚至:
#define kFoo "Bar"
一般来说你不能指望它。但是,您可以使用“sizeof”并将其应用于字符串文字。当然,这意味着您不能按照最初定义的方式定义“kFoo”。
以下内容应该适用于所有编译器和所有优化级别。
#define kFoo "..."
... strcmp(... sizeof(kFoo))