今天遭遇最诡异的事情:改变一下函数名引起运行效率的几十倍差异!

johnfriend 2009-05-04 08:40:02
整个程序如下,其中strncmp()用了库函数的源代码,大家可以直接编译成可执行文件运行一下,只要2秒钟就算完了。
但是诡异的地方在于,当把strncmp()改成其他的任意名字之后,发现速度立马变得很慢,要一分多钟才算完。

太奇怪了,难道连函数名字都会影响速度吗?无语。。。


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

#undef strncmp
int strncmp(const char *, const char *, size_t);
void print_time();

main()
{
char *s1,*s2;
long i;

s1 = (char *) malloc(40);
s2 = (char *) malloc(40);
s1 = "abcdabcdabcd";
s2 = "abcdabcdabcdabcdabcdabcd";
print_time();
for(i=0;i<100000000;i++)
strncmp(s1,s2,20);
print_time();
}

int
strncmp (s1, s2, n)
const char *s1;
const char *s2;
size_t n;
{
unsigned char c1 = '\0';
unsigned char c2 = '\0';

if (n >= 4)
{
size_t n4 = n >> 2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c2 - c1;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c2 - c1;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c2 - c1;
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c2 - c1;
} while (--n4 > 0);
n &= 3;
}

while (n > 0)
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0' || c1 != c2)
return c2 - c1;
n--;
}

return c2 - c1;
}

void print_time()
{
time_t ltime;
ltime = time(NULL);
printf("%s",ctime(<ime));
}
...全文
235 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2009-05-06
  • 打赏
  • 举报
回复
我在red hat 9上试了一下,貌似都是10秒,没差,而且有没有那个#undef strncmp都没有关系。
要不LZ再详细描述下你的环境。
Flyinsky1 2009-05-06
  • 打赏
  • 举报
回复
对不起,我觉得你不止改了名字而已...

f开头的
windsting 2009-05-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 johnfriend 的回复:]
引用 3 楼 wanggang999 的回复:
这有什么诡异的,你觉得
#undef strncmp
这行是干什么的?这就把库函数的strncmp给undefined了?
它又不是宏,怎么可以被undef呢,答案就是:
使用这个函数名的时候,调用的是库函数,没问题,
当该成其他名字,调用的就是你定义的这个函数了,
你总不至于觉得自己的函数比c的库函数还要高效吧,
希望你能接受这个结论。


但是:
(1) 我上面列的strncmp()并不是自己写的,…
[/Quote]
我来道歉的,我昨天仅仅编译运行了一下就盲目的下了结论,
后来我隐藏了声明函数名,发现链接报错,说找不到函数,
添加了std::域解析之后依然如此,我就知道是我错了,
可后来网络断了,死活上不来,今天下班回来赶紧来道歉的。
我为自己的武断、无知和浅薄付出了代价。

顺便等正确答案,我确实不知道该怎么继续分析这个问题了。
johnfriend 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wanggang999 的回复:]
这有什么诡异的,你觉得
#undef strncmp
这行是干什么的?这就把库函数的strncmp给undefined了?
它又不是宏,怎么可以被undef呢,答案就是:
使用这个函数名的时候,调用的是库函数,没问题,
当该成其他名字,调用的就是你定义的这个函数了,
你总不至于觉得自己的函数比c的库函数还要高效吧,
希望你能接受这个结论。
[/Quote]

但是:
(1) 我上面列的strncmp()并不是自己写的,而是GNU的标准库函数的源代码(也就是GCC所用的)。
(2) 但是,为了和系统自带的库函数区别开来,我把strncmp()里面的所有c1-c2 都改成了c2-c1,以使得到的结果符号相反。也就是说如果得到的是97而不是-97,那么就是这里面的strncmp()而不是系统自带的 strncmp()运算出来的结果。
threeleafzerg007 2009-05-04
  • 打赏
  • 举报
回复
呵呵 你貌似用的就是 glibc 2.7的 strncmp的源码吧
T技术沙龙 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wanggang999 的回复:]
这有什么诡异的,你觉得
#undef strncmp
这行是干什么的?这就把库函数的strncmp给undefined了?
它又不是宏,怎么可以被undef呢,答案就是:
使用这个函数名的时候,调用的是库函数,没问题,
当该成其他名字,调用的就是你定义的这个函数了,
你总不至于觉得自己的函数比c的库函数还要高效吧,
希望你能接受这个结论。
[/Quote]
同意
windsting 2009-05-04
  • 打赏
  • 举报
回复
这有什么诡异的,你觉得
#undef strncmp
这行是干什么的?这就把库函数的strncmp给undefined了?
它又不是宏,怎么可以被undef呢,答案就是:
使用这个函数名的时候,调用的是库函数,没问题,
当该成其他名字,调用的就是你定义的这个函数了,
你总不至于觉得自己的函数比c的库函数还要高效吧,
希望你能接受这个结论。
  • 打赏
  • 举报
回复
这么奇怪?一般也别用strncmp这样的名字。
毕竟库文件有这样的名字。
liliangbao 2009-05-04
  • 打赏
  • 举报
回复
帮顶!

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧