Eva*_*oll 6 perl symbols package microbenchmark
请注意,我之前尝试在此问题中对此进行测试,这可能看起来相似,但是这些结果存在缺陷并且是不断折叠的结果,我随后将其禁用。并在此问题中重新发布。
鉴于这两个 evals(评论一个关于执行)只改变&Module::FOO()和&FOO()。
# Symbols imported, and used locally.
eval qq[
package Foo$num;
Module->import();
my \$result = &Module::FOO() * &Module::FOO();
] or die $@;
# Symbols imported, not used locally referencing parent symbol.
eval qq[
package Foo$num;
Module->import();
my \$result = &FOO() * &FOO();
] or die $@;
Run Code Online (Sandbox Code Playgroud)
为什么会顶块占据显着更少的空间?脚本和输出复制如下,
package Module {
use v5.30;
use warnings;
use constant FOO => 42;
use Exporter 'import';
our @EXPORT = ('FOO');
}
package main {
use v5.30;
use autodie;
use warnings;
$|=1;
say "Our PID is $$";
for my $num ( 0..1e5 ) {
eval qq[
package Foo$num;
Module->import();
my \$result = &Module::FOO() * &Module::FOO();
] or die $@;
eval qq[
package Foo$num;
Module->import();
my \$result = &FOO() * &FOO();
] or die $@;
}
say "DONE";
_debug();
}
sub _debug {
open my $fh, "<", "/proc/$$/status";
while ( <$fh> ) {
next unless /Rss/;
print;
}
}
Run Code Online (Sandbox Code Playgroud)
RssAnon: 101856 kB
RssFile: 5228 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
RssAnon: 151528 kB
RssFile: 5224 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
应aquanighton要求直接irc.freenode.net/#perl尝试这个实验constant,这是我使用的代码,
eval qq[
package Foo$num;
use constant FOO => 42;
my \$result = &FOO() * &FOO();
] or die $@;
eval qq[
package Foo$num;
use constant FOO => 42;
my \$result = &Foo${num}::FOO() * &Foo${num}::FOO();
] or die $@;
Run Code Online (Sandbox Code Playgroud)
有了这两个示例,要清楚,直接使用带有常量的变体并通过包限定访问常量实际上更糟糕,然后创建另一个包,该包具有常量 to 和 package-qualify 到那个包裹。
Our PID is 204846
RssAnon: 143560 kB
RssFile: 5196 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
如果导出整个符号而不是全局中的一个插槽,似乎可以非常接近,
our @EXPORT = ('*FOO');
Run Code Online (Sandbox Code Playgroud)
重新运行相同的测试,你会发现两者非常相似
RssAnon: 93900 kB
RssFile: 5228 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
事实上,这更接近理论最大值,这完全不需要调用import,
eval qq[
package Foo$num;
my \$result = &Module::FOO() * &Module::FOO();
] or die $@;
Run Code Online (Sandbox Code Playgroud)
从而产生,
RssAnon: 74528 kB
RssFile: 5160 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
然而,如果我们按照 所建议的那样检查这块荣耀aquanight,
our sub FOO; # top of file
Module->import();
package Bar;
print FOO(); # works
print Bar::FOO(); # does not work
Run Code Online (Sandbox Code Playgroud)
该符号FOO可用于打包Bar,而不会导致包膨胀Bar。当将此方法应用于上述基准测试时,看起来像:
eval qq[
our sub FOO ();
Module->import();
package Foo$num;
my \$result = FOO() * FOO();
] or die $@;
Run Code Online (Sandbox Code Playgroud)
并产生这些结果,
RssAnon: 75112 kB
RssFile: 5284 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)
constant.pm,这可以进一步实现为,
eval qq[
our sub FOO ();
use constant FOO => 42;
package Foo$num;
my \$result = FOO() * FOO();
];
Run Code Online (Sandbox Code Playgroud)
这会产生这些结果,
RssAnon: 75076 kB
RssFile: 5180 kB
RssShmem: 0 kB
Run Code Online (Sandbox Code Playgroud)