Eval()与if()——是否存在性能差异?



我的问题是专门针对Perl的,但我想对大多数语言有所启发。

使用eval()函数和if()语句之间是否存在实际的差异(性能和效率方面)?

eval(-e /path/to/file) or die "file doesn't exist";
if (! -e /path/to/file) { die "file doesn't exist"; }

首先,不要这样进行微优化。编写最容易理解的代码要重要得多。记住这一点将导致更少的bug,避免一个bug比节省大量的纳秒更重要。

也就是说,您可以检查perl如何编译如下内容:

$ perl -MO=Concise,-exec -e '-e "/path/to/file" or die "file doesnx27t exist";'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> pushmark s
7      <$> const[PV "file doesn't exist"] s
8      <@> die[t2] vK/1
9  <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e 'if ( ! -e "/path/to/file") { die "file doesnx27t exist"; }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <1> not sK/1
6  <|> and(other->7) vK/1
7      <0> enter v
8      <;> nextstate(main 1 -e:1) v:{
9      <0> pushmark s
a      <$> const[PV "file doesn't exist"] s
b      <@> die[t2] vK/1
c      <@> leave vKP
d  <@> leave[1 ref] vKP/REFC
-e syntax OK

您可以看到一些琐碎的额外操作涉及到第二个-e结果的逻辑非,进入和离开{}块,以及将die作为单独的语句。这个单独的陈述可能是有用的;如果您在调试器中逐步执行代码,它会在死亡之前停止。

使用Perl 5.12+或在旧版本的Perl中使用unless代替if !将删除not:

$ perl -MO=Concise,-exec -e 'unless (-e "/path/to/file") { die "file doesnx27t exist"; }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> enter v
7      <;> nextstate(main 1 -e:1) v:{
8      <0> pushmark s
9      <$> const[PV "file doesn't exist"] s
a      <@> die[t2] vK/1
b      <@> leave vKP
c  <@> leave[1 ref] vKP/REFC
-e syntax OK

使用语句修饰符产生与-e ... or die代码相同的结果:

$ perl -MO=Concise,-exec -e 'die "file doesnx27t exist" unless -e "/path/to/file";'
1  <0> enter 
2  <;> nextstate(main 1 -e:1) v:{
3  <$> const[PV "/path/to/file"] s
4  <1> ftis sK/1
5  <|> or(other->6) vK/1
6      <0> pushmark s
7      <$> const[PV "file doesn't exist"] s
8      <@> die[t2] vK/1
9  <@> leave[1 ref] vKP/REFC
-e syntax OK

字符串eval (eval EXPR)要求perl在每次执行时编译表达式,这将比计算预编译的表达式要昂贵得多。对于任何提供类似运行时求值机制的语言(JavaScript、Ruby、Python?)

在字符串eval和块eval (eval { BLOCK })中,perl设置了一个错误处理程序,该错误处理程序设置$@,并在发生致命错误时返回到eval语句的末尾。同样,在Perl和任何其他具有捕获异常功能的语言(Python、Java)中,这比简单地执行BLOCK要昂贵得多。

相关内容

最新更新