在 Perl 中,条件可以表示为
if (condition) { do something }
或作为
(condition) and do { do something }
有趣的是,第二种方式似乎快了大约 10%。有谁知道为什么?
在 Perl 中,条件可以表示为
if (condition) { do something }
或作为
(condition) and do { do something }
有趣的是,第二种方式似乎快了大约 10%。有谁知道为什么?
以下关于 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
这只是表明,如果您不知道如何进行正确的代码分析,请不要做这些事情。这两种方法的速度差异在相同的 Big O() 速度范围内(正如@Leon Timmermans 操作码分析所证明的那样)——基准测试只会显示基于其他本地条件的差异,不一定是您的代码。
@Svante 说“and”更快,@shelfoo 说“if”更快。
我的意思是真的...... 1000 万次循环的百分之七秒变化?从统计学上讲,这不是更快或更慢……那是相等的。
与其查看像这样的微小时序,不如学习代码重构和大 O() 表示法……如何减少代码中的循环数……最重要的是,如何使用代码分析器来查看真正的瓶颈是。不要担心统计上微不足道的东西。;)
我已经对它进行了解析,它真的不应该更快。第一个操作码树是
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"
我真的不明白后者怎么会更快。它执行更多操作码!
在平均之前你做了多少测试?非常非常小的偏差在统计上是不显着的!速度在测试之间略有不同的原因有很多。
根据基准,第二个稍慢。可能它与条件有关,但这是一个非常简单的情况的结果:
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)
它也可能取决于 Perl 的版本。你没有提到的。无论如何,差异不足以担心。所以使用任何更有意义的东西。