使用反射 $foo->$bar() 时性能中断

标签 performance perl reflection

我想知道当我使用反射调用名称为字符串的方法时究竟会发生什么:

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/

相关文章:

html - DIV 与 UL、LI 性能

c - C 与汇编程序的效率

perl - 复制数组到哈希

c# - 在 .NET Core 中使用反射

java - 接口(interface)方法的参数上的 @WebParam - 如何获取名称?

mysql - 查询效率

php - 如何提高十亿行表的插入性能?

regex - 如何在递归正则表达式中获得匹配的组?

perl - eval 内出现词法变量为 "not available"的警告的原因是什么

java - 如何使用java反射来确定基类字段的泛型类型