在Perl中,条件可以表示为
1
| if (condition) { do something } |
或as
1
| (condition) and do { do something } |
有趣的是,第二种方法似乎要快10%。有谁知道为什么吗?
有关以下内容的一些评论:
首先,不要使用B :: Terse,这已经过时了。 B :: Concise一旦您习惯了,就会为您提供更好的信息。
第二,您已经使用给定的文字代码运行了它,因此条件被视为恰好是真实的裸字,因此布尔检查在两种情况下都被优化了,这违背了目的。
第三,没有多余的操作码-"空"表示已被优化的操作码(完全不在执行树中,尽管仍在解析树中)。
这是这两种情况的简洁执行树,它们显示为相同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $ perl -MO=Concise,-exec -e'($condition) and do { do something }'
1 <0> enter
2 <;> nextstate(main 2 -e:1) v
3 <#> gvsv[*condition] s
4 <|> and(other->5) vK/1
5 <$> const[PV"something"] s/BARE
6 <1> dofile vK/1
7 <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e'if ($condition) { do something }'
1 <0> enter
2 <;> nextstate(main 3 -e:1) v
3 <#> gvsv[*condition] s
4 <|> and(other->5) vK/1
5 <$> const[PV"something"] s/BARE
6 <1> dofile vK/1
7 <@> leave[1 ref] vKP/REFC
-e syntax OK |
这只是演示,如果您不知道如何执行正确的代码配置文件,请不要执行此操作。这两种方法的速度差异在相同的Big O()速度之内(如@Leon Timmermans opcode分析所证明的那样)-基准只是显示基于其他本地条件(不一定是您的代码)的差异。
@Svante说"和"更快,@ shelfoo说"如果"更快。
我的意思是真的……在一千万次循环中,百分之七十分之一秒的变化?从统计上讲,这不是更快或更慢。...相等。
与其像这样的微小时序,不如了解代码重构和Big O()表示法……如何减少代码中的循环次数……以及最重要的是,如何使用代码探查器进行查看真正的瓶颈在哪里。不用担心统计上无关紧要的东西。 ;)
我已经失望了,它真的不应该更快。第一个的操作码树是
1 2 3 4 5 6 7
| LISTOP (0x8177a18) leave [1]
OP (0x8176590) enter
COP (0x8177a40) nextstate
LISTOP (0x8177b20) scope
OP (0x81779b8) null [174]
UNOP (0x8177c40) dofile
SVOP (0x8177b58) const [1] PV (0x81546e4)"something" |
第二个操作码树是
1 2 3 4 5 6 7 8
| LISTOP (0x8177b28) leave [1]
OP (0x8176598) enter
COP (0x8177a48) nextstate
UNOP (0x8177980) null
LISTOP (0x8177ca0) scope
OP (0x81779c0) null [174]
UNOP (0x8177c48) dofile
SVOP (0x8177b60) const [1] PV (0x81546e4)"something" |
我真的不知道后者会如何更快。它还有一个操作码!
在平均之前,您进行了多少次测试?在统计上,非常非常小的偏差是很小的!在很多测试之间,速度有很多差异的原因很多。
根据基准,第二个稍微慢一些。可能与条件有关,但这是一个非常简单的情况的结果:
1 2 3 4 5 6 7 8
| <wyn>
use Benchmark;
timethese(10000000, {
'if' => '$m=5;if($m > 4){my $i=0;}',
'and' => '$m=5; $m > 4 and do {my $i =0}',
});
</wyn> |
结果:
1 2 3 4 5
| <wyn>
Benchmark: timing 10000000 iterations of Name1, Name2...
if: 3 wallclock secs ( 2.94 usr + 0.01 sys = 2.95 CPU) @ 3389830.51/s (n=10000000)
and: 3 wallclock secs ( 3.01 usr + 0.01 sys = 3.02 CPU) @ 3311258.28/s (n=10000000)
</wyn> |
它也可能取决于Perl的版本。您还没有提到。而且无论如何,区别还不足以担心。因此,请使用更有意义的方法。