2011-04-24 56 views
11

在我的SAX解析XML的回调(的XCode 4,LLVM),我做了很多电话来 这种类型的代码:我可以指望我的编译器优化const char *上的strlen吗?

static const char* kFoo = "Bar"; 

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

    } 


    } 

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

(苹果的示例代码 已预先计算的strlen(kFoo),但我认为这是很容易出错的大量常量字符串的。)

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

+0

初学者优化建议:不要。对专家的优化建议:尚未。除非分析表明这是你的程序中的瓶颈,否则我认为你不应该担心它。 – freespace 2011-04-24 13:24:05

+2

你的意思是'strncmp',对吧?因为你可以使用'strcmp'(带有两个参数),它就等同于当前写入的条件。 – 2011-04-24 13:28:12

+4

@freespace问题是“我可以指望我的编译器优化...?”。除非你认为这个建议适用于编译器,否则我不认为它与这个问题有什么关系。 – 2011-04-24 13:32:30

回答

6

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

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

注意,GCC 4.2.1 -O3不优化此strlen调用,你只能期望它在你的问题(的确切条件下工作尤其是,字符串和调用strlen必须在同一文件)。

+1

我检查了微软的编译器。它还优化了使用'/ O2'优化的呼叫。 – 2011-04-24 13:56:24

+2

如果'kFoo'本身被设置为'const'(例如'static const char * const kFoo =“Bar”;'),gcc会优化'strlen()'的调用。 – caf 2011-04-24 14:21:05

+0

'clang version 2.8'不会在我的机器上没有第二个'const'的情况下优化'strlen()'。 – jfs 2011-04-24 16:42:35

1

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

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

#define kFoo "..." 

    ... strcmp(... sizeof(kFoo)) 
+4

请注意,在这种情况下,sizeof(kFoo)== strlen(kFoo)+ 1( 'sizeof'包含终止'NUL') – vladr 2012-04-06 15:51:47

9

不要写的东西,如:

static const char* kFoo = "Bar"; 

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

也不要写的东西,如:

static const char *const kFoo = "Bar"; 

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

static const char kFoo[] = "Bar"; 

甚至:

#define kFoo "Bar" 
+0

Cool Thanks R. !! – Jacko 2011-04-25 00:54:03

+7

我不会推荐C++中的'#define'选项,绝对不会!感谢指针问题上的负责人。 – 2011-04-26 12:01:54

+1

问题标记为C,而不是C++。但是,无论如何,我宁愿使用'static const char []'形式。 – 2011-04-26 12:15:19

0

后续问题:

你测试了以下?

static std::string const kFoo = "BAR"; 

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

    } 


} 

这是一个可读性的净赢,但我不知道性能成本。作为一种替代方案,如果你必须自己派遣,我发现使用类似状态机的方法(使用堆栈)具有更好的可读性,并且也可能赢得性能(而不是大要打开的标签数量只有现在可以满足的标签)。

+0

谢谢,Matthieu。我正在研究一个称为Ragel的状态机生成器,它可以用多种语言生成解析器。 – Jacko 2011-04-28 13:44:58

相关问题