2

コードのベンチマークをいくつか実行していますが、strstrパフォーマンスを基準点として使用することにしました。私の PC では、約 7 MB のファイル (RAM にプリロード) のすべてのテキストをスキャンするパフォーマンスは、約 10Gb/秒です。
奇妙なことに、strstr 関数のコードを "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\strstr.c" から自分のプログラムにコピーすると、パフォーマンスが大幅に低下しました (約 650 Mb) 。 /秒 コードは次のようなものでした:

char * __cdecl strstr2 (
    char * str1,
    const char * str2
    )
{
    char *cp = (char *) str1;
    char *s1, *s2;

    if ( !*str2 )
        return((char *)str1);

    while (*cp)
    {
        s1 = cp;
        s2 = (char *) str2;

        while ( *s1 && *s2 && !(*s1-*s2) )
            s1++, s2++;

        if (!*s2)
            return(cp);

        cp++;
    }

    return(NULL);

}

リリースですべてのコードをコンパイルし、すべてのコンパイラ オプションはデフォルトで、デバッガーなしで実行します。
この違いは、いくつかのコンパイラ オプションによるものですか、それともコードstrstr.cのコードは、コンパイルされた CRT で使用される実際のコードではありませんか?

QueryPerformanceCounterタイミングを測定するために使用しているUPD 。すべてのテストは 500 回繰り返され、その後、平均速度を計算して次のテストを開始します。(現在、CRT の strstr とコピーされた strstr2 の 2 つのテストを比較しています)

4

1 に答える 1

4

Microsoft CRT は、おそらく にある のアセンブラ バージョンを使用strstrVC\crt\src\intel\strstr.asmます。私のシステム (Visual Studio 10.0) では、内側のループは次のようになります。

loop_start:
        mov     al,[esi]            ; put next char from str1 into al
        add     esi,1               ; increment pointer in str1
in_loop:
        cmp     al,dl
        je      first_char_found

        test    al,al               ; end of str1?
        jnz     loop_start          ; no, go get another char from str1
于 2013-04-05T11:55:02.973 に答える