我们经常使用的strcpy,相信很多人都知道它的实现了,那么有没有想过自己写一个strcpy呢?在C下面,据说这是很经典的实现方法哦,简洁而干净:
char * strcopy2(char * szDst, const char * szSrc)
{
char * szTemp = szDst;
while (*szDst++ = *szSrc++);
szDst = ‘\0’;
return szTemp;
}
不过由于使用的C语言的实现,那么就不可避免会造成C到汇编时的那么框架代码,也就是push ebp; mov ebp, esp; mov esp, ebp; pop ebp等等保存和恢复指针和寄存器等等的操作。
实际的CRT中的strcpy也就是用汇编实现的,那我们就不能自己来一个自己的strcpy么?当然也用汇编写,我还给它穿一个C的皮:)
__declspec(naked) char * strcopy(char * szDst, const char * szSrc)
{
__asm
{
mov eax, [esp+4] //szDst
mov edx, [esp+8] //szSrc
Begin:
mov cl, byte ptr[edx]
cmp cl, 0x0
je End
mov byte ptr[eax], cl
inc eax
inc edx
jmp Begin
End:
mov byte ptr[eax], 0x0
mov eax, [esp+4]
ret
}
}
使用__declspec(naked)预编译指令,那么C函数将不会产生那些讨厌的什么push ebp等等的框架指令:俺的函数很小,俺只有有限的几个寄存器,干什么要先保存那么多,然后又恢复呢?产生一大堆的没用操作,所以,俺就按照上面的方式干了哦:)
不过实际测试的效果显示,使用CRT库中的strcpy函数的效率还是比较高,为什么我这里的strcopy还不如CRT库中的strcpy效率高呢?什么原因,请大家帮忙分析一下啦!
几种情况的效率测试:
一. 使用CRT库中的strcpy函数
int main(int argc, char* argv[])
{
char * p1 = "China";
char p[20];
printf("Start time: %08d\n", GetTickCount());
for (int i = 0; i < 10000000; i++) {
strcpy(p, p1);
}
printf("End time: %08d\n", GetTickCount());
return 0;
}
结果为:
Start time: 29515000
End time: 29515120
耗时:120ms;
二. 使用上面的strcopy函数,也就是我自己的汇编实现:
更改如上测试程序中的strcpy函数为我自己实现strcopy函数,结果为:
Start time: 29540947
End time: 29541147
耗时:200ms;
三. 使用上面的纯C编写的strcopy2函数:
更改如上测试程序中的strcpy函数为已经定义的strcopy2函数,结果为:
Start time: 29727525
End time: 29728327
耗时:805ms。
从时间消耗的时间上来看,显然是CRT库中strcpy表现最佳,而我的实现其次,表现最差的就是使用纯C编写的strcopy2了。
没有看CRT库中的strcpy的实现,哪位看过的可以先给我说说是怎么回事,为什么我的strcopy效率会比较底呢?谢谢了!