2016-03-22 25 views
-3

strchr()より遅いです。私はそれがVS 2015の同じ実装だと仮定します。新しい関数でコピーして試しました。私はarray[15001767](ヒープに格納されている)の文字に大きな違いがあります。元の3ミリ秒、17ミリ秒の鉱山です。私のstrchr()は、Visual Studio 2015

この相違点はどこにありますか?あなたが異なるstrchr私は標準ライブラリを使用して、アップノック実装(MSVC)、OPの機能、および文字列を告げているそのうちの一つ2つのアセンブラのバージョン、この比較に興味があるかもしれない

char *teststr(const char *s, int c) 
{ 
    while (*s != (char)c) 
     if (!*s++) 
      return 0; 
    return (char *)s; 
} 

int main() 
{ 
    DWORD pa; 

    char *test = (char*)HeapAlloc(HeapCreate(NULL, 0, 0), NULL, 15001767); 
    ReadFile(CreateFileW(L"MyFile.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL), test, 15001767, &pa, NULL); 

    //strchr(test, '£'); 
    teststr(test, '£'); 

}

+0

はおそらく、彼らは 'REPNE scasb'命令を使用して、アセンブラで書かれています。 –

+1

標準ライブラリの名前は実装のための予約です。あなたのコードでそれらを使用しないでください。また**あなたはそれにリンクするだけでなく、**のコード**を提供する必要があります。 – Olaf

+0

私は明らかに私の機能の名前を変更しました。私が作ったテストでは、新しい機能がなくても、私は同じ持続時間が約17msです。 – Kdmeizk

答えて

2

長さ、もう一方はそれを最初に見つけなければならない。その2番目はOPのルーチンよりもまだ高速です。

#include <stdio.h> 
#include <string.h> 
#include <time.h> 

#define LEN 15001767 
#define REPS 100 

char array[LEN]; 

char *asmstrchrA(const char *s, int c) 
// knows the string length 
{ 
    __asm { 
     push es 
     mov  ax,ds 
     mov  es,ax 
     mov  edi,s 
     mov  ecx,LEN 
     mov  eax,c 
     cld 
     repne scasb 
     jz  foundA 
     xor  edi,edi   ; not found 
     inc  edi 
    foundA: 
     dec  edi 
     mov  s,edi 
     pop  es 
    } 
    return (char *)s; 
}  

char *asmstrchrB(const char *s, int c) 
// finds the string length first 
{ 
    __asm { 
     push es 
     mov  ax,ds 
     mov  es,ax 

     mov  edi,s   ; find string length 
     xor  eax,eax 
     mov  ecx,-1 
     cld 
     repne scasb 
     mov  ecx,edi 
     sub  ecx,s 

     mov  edi,s   ; find char 
     mov  eax,c 
     cld 
     repne scasb 
     jz  foundB 
     xor  edi,edi   ; not found 
     inc  edi 
    foundB: 
     dec  edi 
     mov  s,edi 
     pop  es 
    } 
    return (char *)s; 
}  

char *OPstrchr(const char *s, int c) 
// from OP's link 
{ 
    while (*s != (char)c) 
     if (!*s++) 
      return 0; 
    return (char *)s; 
}  

int main (void) { 
    clock_t start; 
    int i; 
    char * cptr; 

    memset(array, '1', LEN-1); 
    array[LEN-5] = '2'; 

    start = clock(); 
    for(i=0; i<REPS; i++) 
     cptr = OPstrchr(array, '2'); 
    printf("OPstrchr %p, time = %f seconds\n", (void*)cptr, (double)(clock() - start)/CLOCKS_PER_SEC); 

    start = clock(); 
    for(i=0; i<REPS; i++) 
     cptr = asmstrchrA(array, '2'); 
    printf("asmstrchrA %p, time = %f seconds\n", (void*)cptr, (double)(clock() - start)/CLOCKS_PER_SEC); 

    start = clock(); 
    for(i=0; i<REPS; i++) 
     cptr = asmstrchrB(array, '2'); 
    printf("asmstrchrB %p, time = %f seconds\n", (void*)cptr, (double)(clock() - start)/CLOCKS_PER_SEC); 

    start = clock(); 
    for(i=0; i<REPS; i++) 
     cptr = strchr(array, '2'); 
    printf("strchr  %p, time = %f seconds\n", (void*)cptr, (double)(clock() - start)/CLOCKS_PER_SEC); 
return 0; 
} 

プログラムの出力:

OPstrchr 0125F5A2, time = 7.488000 seconds 
asmstrchrA 0125F5A2, time = 1.248000 seconds 
asmstrchrB 0125F5A2, time = 2.512000 seconds 
strchr  0125F5A2, time = 1.045000 seconds 
+0

私の目的は、[strrchr()](http://clc-wiki.net/wiki/strrchr)が見つかった各文字に対して書き込みを行い、位置0から開始するため、 'strchr()'逆関数を見つけることです。私は無駄な書き込み+開始位置0を避けたいと思います。なぜなら、遅いと思うからです。逆の機能を見つけられなかったので手作業で試してみましたが、この恐ろしい期間がありました。 – Kdmeizk

+1

申し訳ありません、これは今、別の質問ですか? 'strrchr'は文字列の最後から始まり、逆方向に走査します。何が書かれますか? –

+0

はい、リンクされた質問です。私はファイルの終わりにcharを置くと、 'strchr()'と 'strrchr()'がそれを検索する時間が同じであるため、位置0で始まると仮定しました。 – Kdmeizk

関連する問題