我的strchr()比原始的Visual Studio 2015慢

时间:2016-03-22 17:17:50

标签: c windows visual-studio

strchr()。我假设它在VS 2015中是相同的实现。我将它复制到一个新函数中并尝试过。我对char array[15001767](存储在堆中),3 ms原始,17 ms我的内容有很大的不同。

这个差异在哪里?

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, '£');

}

1 个答案:

答案 0 :(得分:2)

您可能对我使用标准库(MSVC),OP的函数和两个汇编程序版本的不同strchr实现的比较感兴趣,其中一个被告知字符串长度,另一个有首先找到它。第二个仍然比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