有两个比较两个值大小的函数,看哪个更快?

xz1983546 2010-01-30 03:21:14
下面两个都是内联函数一个很常见,一个不怎么常见连比较操作有关的都没用到。
inline int min( int a, int b)
{
return a>b?b:a;
}

inline int min( int a, int b)
{
int mask = (a - b) >> 31;
return (a & mask) | (b & ~mask);
}
...全文
729 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
ffjj56 2011-09-10
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 yzx714 的回复:]
让编译器来为我们解答!
第一个的汇编代码:

Assembly code

00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 8B550C mov edx,[ebp+0xc]
00000006 8B4508 mov……
[/Quote]
这不就妥了
ningweidong 2011-09-10
  • 打赏
  • 举报
回复
没什么区别
guochurun 2011-09-09
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 bluestar2009 的回复:]
引用 30 楼 yzx714 的回复:
让编译器来为我们解答!
第一个的汇编代码:
Assembly code0000000055push ebp00000001 89E5mov ebp,esp00000003 8B550Cmov edx,[ebp+0xc]00000006 8B4508mov eax,[ebp+0x8]
00000009 39D0cmp eax,edx
0000000B……
[/Quote]牛牛B!
零基础 2011-09-08
  • 打赏
  • 举报
回复
太牛叉了,这么简单的事情都考虑这么多办法,不过话说钻牛角尖也不太好吧?
wizard_tiger 2011-09-08
  • 打赏
  • 举报
回复
个人更喜欢第一种。
赵4老师 2011-09-08
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 yzx714 的回复:]
让编译器来为我们解答!
第一个的汇编代码:

Assembly code
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 8B550C mov edx,[ebp+0xc]
00000006 8B4508 mov e……
[/Quote]
支持!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
Dadur 2011-09-08
  • 打赏
  • 举报
回复
不同环境下 int 不一定会是4位。
所以用>>31,这种不是很好。
yazh2636 2011-09-06
  • 打赏
  • 举报
回复
学习 学习!
0153 2011-09-06
  • 打赏
  • 举报
回复
减法不太可取,以下程序中输出相反:
inline int min( int a, int b)
{
int mask = (a - b) >> 31;
return (a & mask) | (b & ~mask);
}
int main(void)
{
int i = -1500000000;
int j = 1500000000;
printf("min=%d", min(i, j));
return 0;
}


希望楼主仔细了解一下:
sub eax,ebx
jl _@1
jb _@2
有什么区别
workhard20 2011-09-06
  • 打赏
  • 举报
回复
顶30楼,我喜欢
Alimer 2011-09-04
  • 打赏
  • 举报
回复
学习了,谢谢...
Plug-Ins 2011-09-04
  • 打赏
  • 举报
回复
30楼,- -!牛B!!!
哈哈来了了 2010-02-07
  • 打赏
  • 举报
回复
进来学习一下 看来自己要学的东西很多
bluestar2009 2010-02-04
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 yzx714 的回复:]
让编译器来为我们解答!
第一个的汇编代码:
Assembly code0000000055push ebp00000001 89E5mov ebp,esp00000003 8B550Cmov edx,[ebp+0xc]00000006 8B4508mov eax,[ebp+0x8]
00000009 39D0cmp eax,edx
0000000B 7E02jng0xf
0000000D 89D0mov eax,edx
0000000F 5Dpop ebp00000010 C3ret
第二个的汇编代码:
Assembly code0000000055push ebp00000001 89E5mov ebp,esp00000003 83EC10sub esp,byte +0x1000000006 8B450Cmov eax,[ebp+0xc]
00000009 8B5508mov edx,[ebp+0x8]
0000000C 89D1mov ecx,edx
0000000E 29C1sub ecx,eax00000010 89C8mov eax,ecx00000012 C1F81Fsar eax,0x1f00000015 8945FCmov [ebp-0x4],eax
00000018 8B45FCmov eax,[ebp-0x4]
0000001B 8B5508mov edx,[ebp+0x8]
0000001E 21C2and edx,eax00000020 8B45FCmov eax,[ebp-0x4]00000023 F7D0not eax00000025 23450Cand eax,[ebp+0xc]
00000028 09D0or eax,edx
0000002A C9leave
0000002B C3ret
我是Linux下gcc 4.4.1
我想从代码的复杂度来看很容易看出哪个的效率高。第二个是明显的舍近求远。
让我们继续做一个实验,执行两段代码一万次,看哪个的耗时少。
下面是测试程序:
C/C++ code#include<sys/time.h>
#include<stdio.h>int min1(int a,int b)
{return a>b?b:a;
}int min2(int a,int b)
{int mask= (a- b)>>31;return (a& mask)| (b&~mask);
}int main()
{struct timeval t,end;
gettimeofday(&t,NULL);int i=0;while(i++<10000){
min1(1,2);
}
gettimeofday(&end,NULL);
printf("%lfsec,%lfusec\n",(double)end.tv_sec-t.tv_sec,(double)end.tv_usec-t.tv_usec);

gettimeofday(&t,NULL);
i=0;while(i++<10000){
min2(1,2);
}
gettimeofday(&end,NULL);
printf("%lfsec,%lfusec\n",(double)end.tv_sec-t.tv_sec,(double)end.tv_usec-t.tv_usec);return0;
}
我获得的输出是:
0.000000sec,177.000000usec
0.000000sec,256.000000usec
很明显,简单的那个快
[/Quote]

牛B!!!!
yzx714 2010-02-03
  • 打赏
  • 举报
回复
让编译器来为我们解答!
第一个的汇编代码:
00000000  55                push ebp
00000001 89E5 mov ebp,esp
00000003 8B550C mov edx,[ebp+0xc]
00000006 8B4508 mov eax,[ebp+0x8]
00000009 39D0 cmp eax,edx
0000000B 7E02 jng 0xf
0000000D 89D0 mov eax,edx
0000000F 5D pop ebp
00000010 C3 ret

第二个的汇编代码:
00000000  55                push ebp
00000001 89E5 mov ebp,esp
00000003 83EC10 sub esp,byte +0x10
00000006 8B450C mov eax,[ebp+0xc]
00000009 8B5508 mov edx,[ebp+0x8]
0000000C 89D1 mov ecx,edx
0000000E 29C1 sub ecx,eax
00000010 89C8 mov eax,ecx
00000012 C1F81F sar eax,0x1f
00000015 8945FC mov [ebp-0x4],eax
00000018 8B45FC mov eax,[ebp-0x4]
0000001B 8B5508 mov edx,[ebp+0x8]
0000001E 21C2 and edx,eax
00000020 8B45FC mov eax,[ebp-0x4]
00000023 F7D0 not eax
00000025 23450C and eax,[ebp+0xc]
00000028 09D0 or eax,edx
0000002A C9 leave
0000002B C3 ret

我是Linux下gcc 4.4.1
我想从代码的复杂度来看很容易看出哪个的效率高。第二个是明显的舍近求远。
让我们继续做一个实验,执行两段代码一万次,看哪个的耗时少。
下面是测试程序:
#include <sys/time.h>
#include <stdio.h>
int min1(int a,int b)
{
return a>b?b:a;
}
int min2(int a,int b)
{

int mask = (a - b) >> 31;
return (a & mask) | (b & ~mask);
}
int main()
{
struct timeval t,end;
gettimeofday(&t,NULL);
int i=0;
while(i++<10000){
min1(1,2);
}
gettimeofday(&end,NULL);
printf("%lfsec,%lfusec\n",(double)end.tv_sec-t.tv_sec,(double)end.tv_usec-t.tv_usec);

gettimeofday(&t,NULL);
i=0;
while(i++<10000){
min2(1,2);
}
gettimeofday(&end,NULL);
printf("%lfsec,%lfusec\n",(double)end.tv_sec-t.tv_sec,(double)end.tv_usec-t.tv_usec);

return 0;
}

我获得的输出是:
0.000000sec,177.000000usec
0.000000sec,256.000000usec
很明显,简单的那个快
worldemperor 2010-02-03
  • 打赏
  • 举报
回复
嗯,其实我觉得,循环上1w次,看看哪个需要时间少,哪个就快,用事实来检验吧.
honghu069 2010-02-02
  • 打赏
  • 举报
回复
看编译器有没有优化了
一般来说,还是第一个快
wjy4688 2010-02-02
  • 打赏
  • 举报
回复
一看就是第一个快
aslprince 2010-02-01
  • 打赏
  • 举报
回复
溢出的值不是不定的么??
那不是和平台还有编译器有关系??
那就有可能出现意外了??
ArthurJava 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 fo1_sky 的回复:]
引用 23 楼 arthurjava 的回复:
a-b会溢出的

要的就是溢出
[/Quote]
a-b的溢出是与31这个数字相关的,在其他平台上不一定可以确切运行
加载更多回复(24)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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