我想知道当我使用反射调用名称为字符串的方法时究竟会发生什么:
my $foo = Foo->new();
my $method = 'myMethod';
$foo->$method();
比本地调用慢约 20%:
$foo->myMethod();
任何有关如何实现 perl 反射的文档的指针都会有所帮助。
谢谢。
最佳答案
> perl -MO=Concise -e '$foo->$bar'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
7 <1> entersub[t3] vKS/TARG ->8
3 <0> pushmark s ->4
- <1> ex-rv2sv sKM/1 ->5
4 <#> gvsv[*foo] s ->5
6 <1> method K/1 ->7 # ops to read $bar and then call method
- <1> ex-rv2sv sK/1 ->6 #
5 <#> gvsv[*bar] s ->6 #
-e syntax OK
> perl -MO=Concise -e '$foo->bar'
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <1> entersub[t2] vKS/TARG ->7
3 <0> pushmark s ->4
- <1> ex-rv2sv sKM/1 ->5
4 <#> gvsv[*foo] s ->5
5 <$> method_named[PV "bar"] ->6 # op to call the 'bar' method
-e syntax OK
在第一个例子中,perl 必须加载
$bar
变量,然后检查它是否包含可用作方法的名称或值。内容自$bar
可能会在调用之间发生变化,每次都必须进行此查找。在第二个例子中,perl 已经知道字符串
"bar"
应该用作方法名称,这样可以避免在每次执行时加载变量并检查其内容。但是您不必太担心两个 native 操作之间 20% 的速度差异。主要是因为 native 操作非常快,并且它们实际需要的任何速度很快就会被您的代码必须执行的实际算法相形见绌。换句话说,除非您使用代码分析器将此问题隔离为热点,否则速度差异的教学意义大于实际意义。
关于使用反射 $foo->$bar() 时性能中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8357498/