我的strchr()比最初的Visual Studio 2015慢
。我假设在VS 2015中的实现是相同的。我在一个新函数中复制了它并尝试了。我对堆中存储的字符数组[15001767]有很大的不同,3毫秒原始,17毫秒我的 这种差异在哪里我的strchr()比最初的Visual Studio 2015慢,c,windows,visual-studio,C,Windows,Visual Studio,。我假设在VS 2015中的实现是相同的。我在一个新函数中复制了它并尝试了。我对堆中存储的字符数组[15001767]有很大的不同,3毫秒原始,17毫秒我的 这种差异在哪里 char *teststr(const char *s, int c) { while (*s != (char)c) if (!*s++) return 0; return (char *)s; } int main() { DWORD pa; c
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, '£');
}您可能会对我使用标准库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;
}
也许它们是使用repne scasb指令在汇编程序中编写的。标准库的名称是实现的保留名称。不要在代码中使用它们。你还需要提供问题中的代码,而不仅仅是链接。我显然改变了我函数的名称。在我做的任何测试中,即使没有新的功能,我也有大约17毫秒的持续时间。如果你为每个人展示汇编程序,请考虑把问题弄清楚,并通过张贴相关的代码来展示你的努力。我的目标是找到一个StruChr反函数。因为为找到的每个字符写入数据并从零开始。我希望避免无用的写入+开始位置0,因为我假设它比较慢。当我手动尝试它时,因为我没有找到反向函数,我得到了这个可怕的持续时间。对不起,这是一个不同的问题吗?strrchr将从字符串的末尾开始,并向后扫描。写什么?是的,这是一个关联的问题。我只假设它从位置0开始,因为文件末尾有一个字符,strchr和strrchr搜索它的时间是相同的。它必须从位置0开始,因为C不知道字符串长度。因此,它要么找到字符串长度,然后向后执行ref 1,要么像您的strchr示例那样合并这两个操作。碰巧,当我实现ref 1时,我的汇编程序strrchr比库稍微快一点,但可能只是因为搜索的字符接近字符串的末尾。是的,可能是因为字符位于字符串的末尾。那么,我唯一的方法就是编写自己的strrchr实现?没有比汇编程序更好的方法了?
OPstrchr 0125F5A2, time = 7.488000 seconds
asmstrchrA 0125F5A2, time = 1.248000 seconds
asmstrchrB 0125F5A2, time = 2.512000 seconds
strchr 0125F5A2, time = 1.045000 seconds