or和in的速度 ( 积分: 80 )

  • 主题发起人 主题发起人 choosejing
  • 开始时间 开始时间
C

choosejing

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一语句if (a=1)or (b=1)or(c=1)or(d=1)or(e=1) then showmessage('ss')
那个or可能会更多,所以想问下这里用or或者用in或者其他的哪个函数的速度会更快
 
用or的话,从左往右,只要有一个条件成立,后面的就不会再判断了
 
汇编里只有 or, in 是端口操作.
 
to lxw5214:
但是我的那条件在单次执行的时候只有一个条件会成立
to 白河愁
我说的是在delphi 中的
 
to choosejing:
你的意思是 Delphi 不会把代码编译成 2 进制执行?
 
如果在默认的
Project - Syntax options - Complete boolean eval
不被选中的情况下效率应该差不多,if语句只要判断到一个条件成立就结束判断了速度快;

如果选中了这项那么肯定比不上in快,in可不管这套。
我想大概这样,如果让你设计in语句的ObjectPascal实现,难道你非得遍历全部元素才告诉结果那你傻子。
 
多人接受答案了。
 
楼主说的In是Pascal的In操作符吧

情况1.Or方式
if (a=1)or (b=1)or(c=1)or(d=1)or(e=1) then
showmessage('ss');
Unit1.pas.35: if (a=1)or (b=1)or(c=1)or(d=1)or(e=1) then
0045A866 83FB01 cmp ebx,$01
0045A869 7415 jz $0045a880
0045A86B 83FE01 cmp esi,$01
0045A86E 7410 jz $0045a880
0045A870 83FF01 cmp edi,$01
0045A873 740B jz $0045a880
0045A875 83FD01 cmp ebp,$01
0045A878 7406 jz $0045a880
0045A87A 833C2401 cmp dword ptr [esp],$01
0045A87E 750A jnz $0045a88a
Unit1.pas.36: showmessage('ss');
0045A880 B804A94500 mov eax,$0045a904
0045A885 E8AE26FDFF call ShowMessage
//用的是比较的方式,比较到符合条件的项则跳转到ShowMessage这行,最后一项比较是不同则跳出If之外
情况2.In 集合项是变量方式
if 1 in [a, b, c, d, e] then
ShowMessage('');

Unit1.pas.36: if 1 in [a, b, c, d, e] then
0045A866 8BD3 mov edx,ebx
0045A868 8D442404 lea eax,[esp+$04]
0045A86C B120 mov cl,$20
0045A86E E88D8CFAFF call @SetElem
0045A873 8BC6 mov eax,esi
0045A875 3DFF000000 cmp eax,$000000ff
0045A87A 7705 jnbe $0045a881
0045A87C 0FAB442404 bts [esp+$04],eax
0045A881 8BC7 mov eax,edi
0045A883 3DFF000000 cmp eax,$000000ff
0045A888 7705 jnbe $0045a88f
0045A88A 0FAB442404 bts [esp+$04],eax
0045A88F 8BC5 mov eax,ebp
0045A891 3DFF000000 cmp eax,$000000ff
0045A896 7705 jnbe $0045a89d
0045A898 0FAB442404 bts [esp+$04],eax
0045A89D 8B0424 mov eax,[esp]
0045A8A0 3DFF000000 cmp eax,$000000ff
0045A8A5 7705 jnbe $0045a8ac
0045A8A7 0FAB442404 bts [esp+$04],eax
0045A8AC F644240402 test byte ptr [esp+$04],$02
0045A8B1 7407 jz $0045a8ba
Unit1.pas.37: ShowMessage('');
0045A8B3 33C0 xor eax,eax
0045A8B5 E87E26FDFF call ShowMessage
//用位测试的方式比较每一项,每一项都要被执行一次
情况三.In的集合里面是常量的方式
if a in [1..5,20..30, 100] then
showmessage('ss');
Unit1.pas.41: if a in [1..5,20..30, 100] then
0045A825 48 dec eax
0045A826 83E805 sub eax,$05 //-5看看是否是0
0045A829 720D jb $0045a838
0045A82B 83C0F2 add eax,-$0e //e = 20 - 5 - 1
0045A82E 83E80B sub eax,$0b //b = 20 - 20 + 1
0045A831 7205 jb $0045a838
0045A833 83E845 sub eax,$45
0045A836 750A jnz $0045a842
Unit1.pas.42: showmessage('ss');
0045A838 B84CA84500 mov eax,$0045a84c
0045A83D E8D226FDFF call ShowMessage
如果集合是连续的就用比较的数减前面的最大数,然后减最大值看是否是0

可见如果用于比较的数据是变量的话最好是用or串联起来比较.
如果用于比较的是常量的话并且有很多是连续的那么In效率要高很多,因为它是通过减法运算计算的.而不是一项一项比较
 
后退
顶部