在Perl中,条件可以表示为
if (condition) { do something }
或
(condition) and do { do something }
有趣的是,第二种方式似乎要快10%左右。有谁知道为什么?
答案 0 :(得分:18)
关于下面的deparse的一些评论:
首先,不要使用B :: Terse,它已经过时了。一旦习惯,B :: Concise就会为您提供更好的信息。
其次,您使用给定的文字代码运行它,因此条件被视为一个恰好为真的裸字,因此布尔检查在两种情况下都被优化掉了,哪种方法会失败。
第三,没有额外的操作码 - “null”表示已被优化掉的操作码(完全在执行树之外,但仍在解析树中。)
这是两种情况的简明执行树,它们将它们显示为相同:
$ 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
答案 1 :(得分:11)
我已经贬低了它,它真的不应该更快。第一个的操作码树是
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"
第二个的操作码树是
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"
我真的不知道后者如何更快。它做了更多的操作码!
答案 2 :(得分:11)
如果您不知道如何进行正确的代码分析,那么就不要这样做了。这两种方法的速度差异在相同的Big O()速度内(由@Leon Timmermans操作码分析证明) - 基准测试只是根据其他本地条件显示差异,而不一定是您的代码。
我的意思是......千万次循环的变化是7百分之一秒?这不是更快或更慢,从统计学上来说......这是相等的。
不要看这样的微不足道的时间,而是学习代码重构和Big O()表示法...如何减少代码中的循环次数......最重要的是,如何使用代码分析器来查看真正的瓶颈在哪里。不要担心统计上无关紧要的东西。 ;)
答案 3 :(得分:3)
在平均之前你做了多少次测试?非常非常小的偏差在统计上是微不足道的!测试之间的速度差异有很多原因。
答案 4 :(得分:2)
根据Benchmark的说法,第二个稍慢。可能它与条件有关,但这是一个非常简单的结果:
use Benchmark;
timethese(10000000, {
'if' => '$m=5;if($m > 4){my $i=0;}',
'and' => '$m=5; $m > 4 and do {my $i =0}',
});
结果:
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)
答案 5 :(得分:0)
它还可能取决于Perl的版本。你没有提到过。无论如何,差异还不足以让人担心。所以使用更有意义的东西。