16

私の 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) が事前に計算されていましたが、これは多数の定数文字列に対してエラーが発生しやすいと思います。)

編集: 最適化の動機: iPod touch 2G で SVG マップを解析するには、NSXMLParser を使用して 5 秒 (!) かかります。そこで、lib2xml に切り替えて、文字列比較を最適化します。

4

4 に答える 4

12

次のようなことは書かないでください。

static const char* kFoo = "Bar";

定数データを指すという名前の変数を作成しました。kFooコンパイラは、この変数が変更されていないことを検出して最適化できる場合がありますが、そうでない場合は、プログラムのデータ セグメントが肥大化しています。

また、次のような書き込みはしないでください。

static const char *const kFoo = "Bar";

これで、変数kFooconst修飾され、変更できなくなりましたが、位置に依存しないコード (共有ライブラリなど) で使用されている場合、内容は実行時に変化するため、起動とメモリのコストがプログラムに追加されます。代わりに、次を使用します。

static const char kFoo[] = "Bar";

あるいは:

#define kFoo "Bar"
于 2011-04-24T19:47:35.333 に答える
12

「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 番目の引数がすぐに置き換えられてい$3ます。

gcc 4.2.1 -O3 はこの呼び出しを最適化しないことに注意してstrlenください。また、質問の正確な条件でのみ動作することが期待できることに注意してください (特に、文字列とへの呼び出しstrlenは同じファイルにある必要があります)。

于 2011-04-24T13:46:55.603 に答える
2

一般的に、あなたはそれを当てにすることはできません。ただし、「sizeof」を使用して文字列リテラルに適用することはできます。もちろん、これは 'kFoo' を最初に定義された方法で定義できないことを意味します。

以下は、すべてのコンパイラとすべての最適化レベルで機能するはずです。

#define kFoo "..."

    ... strcmp(... sizeof(kFoo))
于 2011-04-24T16:17:35.620 に答える
0

フォローアップの質問:

以下をテストしましたか?

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

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

  }


}

読みやすさの点では正味の勝利ですが、パフォーマンスのコストについてはわかりません。

別の方法として、自分でディスパッチする必要がある場合は、(スタックを使用して) ステート マシンのようなアプローチを使用すると、読みやすさの点ではるかに優れており、パフォーマンスの点でも勝つ可能性があることがわかりました (大量のタグを使用する代わりに)。スイッチをオンにすると、現在満たすことができるタグしかありません)。

于 2011-04-26T12:15:53.997 に答える