在我的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,并优化字符串比较。
答案 0 :(得分: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
...
我将strcmp
更改为strncmp
,但第三个参数确实已被替换为$3
。
请注意,gcc 4.2.1 -O3不会优化此strlen
调用,并且您只能期望它在您的问题的精确条件下工作(尤其是字符串和对{{1的调用)必须在同一个文件中。)
答案 1 :(得分:10)
不要写像:
static const char* kFoo = "Bar";
您创建了一个名为kFoo
的变量,它指向常量数据。编译器可能能够检测到这个变量没有改变并优化它,但如果没有,你的程序的数据段就会膨胀。
也不要写像:
static const char *const kFoo = "Bar";
现在你的变量kFoo
是const
- 合格且不可修改,但如果它用于位置无关代码(共享库等),则内容在运行时仍会有所不同,因此它将会为您的程序添加启动和内存成本。相反,使用:
static const char kFoo[] = "Bar";
甚至:
#define kFoo "Bar"
答案 2 :(得分:2)
一般来说,你不能指望它。但是,您可以使用'sizeof'并将其应用于字符串文字。当然,这意味着您无法按照最初定义的方式定义'kFoo'。
以下内容适用于所有编译器和所有优化级别。
#define kFoo "..."
... strcmp(... sizeof(kFoo))
答案 3 :(得分:0)
后续问题:
您是否测试过以下内容?
static std::string const kFoo = "BAR";
void SaxCallBack(char* sax_string,.....)
{
if ( sax_string == kFoo)
{
}
}
这是可读性的净赢,但我不知道性能成本。
作为替代方案,如果你必须自己发送,我发现使用类似状态机的方法(使用堆栈)更好的可读性,并且也可能在性能方面取得胜利(而不是拥有大量数据)打开的标签只有你现在可以使用的标签。