为什么符号的包限定导致使用的内存更少,即使符号是在本地导入的?
Why does the package qualification of symbols result in less memory used, even if the symbols are imported locally?
注意,我尝试了, however those results were flawed and a 并在这个问题中重新发布。
给定这两个 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 $@;
为什么顶部块占用 大大 更少 space?脚本和输出转载如下,
脚本
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;
}
}
结果
包裹(名称space)合格
RssAnon: 101856 kB
RssFile: 5228 kB
RssShmem: 0 kB
本地进口
RssAnon: 151528 kB
RssFile: 5224 kB
RssShmem: 0 kB
更新
aquanight
在 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 $@;
通过这样执行两个示例,要清楚的是,直接使用带有常量的变体并通过包限定访问常量实际上更糟糕,然后它是创建另一个包,该包具有该包的常量和 package-qualify。
Our PID is 204846
RssAnon: 143560 kB
RssFile: 5196 kB
RssShmem: 0 kB
导出整个符号
如果导出 整个符号 而不是 glob 中的一个插槽,似乎可以非常接近,
our @EXPORT = ('*FOO');
再运行同样的测试,你会发现两者很相似
RssAnon: 93900 kB
RssFile: 5228 kB
RssShmem: 0 kB
事实上,这更接近理论最大值,它完全切断了对 import
的调用,
eval qq[
package Foo$num;
my $result = &Module::FOO() * &Module::FOO();
] or die $@;
产生,
RssAnon: 74528 kB
RssFile: 5160 kB
RssShmem: 0 kB
也许,最大的黑魔法乐趣。
然而,如果我们按照 aquanight
、
的建议检查这块荣耀
our sub FOO; # top of file
Module->import();
package Bar;
print FOO(); # works
print Bar::FOO(); # does not work
符号 FOO
可用于包 Bar
而不会膨胀 Bar
包。当此方法应用于上述基准测试时,它看起来像,
eval qq[
our sub FOO ();
Module->import();
package Foo$num;
my $result = FOO() * FOO();
] or die $@;
并产生这些结果,
RssAnon: 75112 kB
RssFile: 5284 kB
RssShmem: 0 kB
和constant.pm
,
这可以进一步实现为,
eval qq[
our sub FOO ();
use constant FOO => 42;
package Foo$num;
my $result = FOO() * FOO();
];
这将产生这些结果,
RssAnon: 75076 kB
RssFile: 5180 kB
RssShmem: 0 kB
注意,我尝试了
给定这两个 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 $@;
为什么顶部块占用 大大 更少 space?脚本和输出转载如下,
脚本
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;
}
}
结果
包裹(名称space)合格
RssAnon: 101856 kB
RssFile: 5228 kB
RssShmem: 0 kB
本地进口
RssAnon: 151528 kB
RssFile: 5224 kB
RssShmem: 0 kB
更新
aquanight
在 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 $@;
通过这样执行两个示例,要清楚的是,直接使用带有常量的变体并通过包限定访问常量实际上更糟糕,然后它是创建另一个包,该包具有该包的常量和 package-qualify。
Our PID is 204846
RssAnon: 143560 kB
RssFile: 5196 kB
RssShmem: 0 kB
导出整个符号
如果导出 整个符号 而不是 glob 中的一个插槽,似乎可以非常接近,
our @EXPORT = ('*FOO');
再运行同样的测试,你会发现两者很相似
RssAnon: 93900 kB
RssFile: 5228 kB
RssShmem: 0 kB
事实上,这更接近理论最大值,它完全切断了对 import
的调用,
eval qq[
package Foo$num;
my $result = &Module::FOO() * &Module::FOO();
] or die $@;
产生,
RssAnon: 74528 kB
RssFile: 5160 kB
RssShmem: 0 kB
也许,最大的黑魔法乐趣。
然而,如果我们按照 aquanight
、
our sub FOO; # top of file
Module->import();
package Bar;
print FOO(); # works
print Bar::FOO(); # does not work
符号 FOO
可用于包 Bar
而不会膨胀 Bar
包。当此方法应用于上述基准测试时,它看起来像,
eval qq[
our sub FOO ();
Module->import();
package Foo$num;
my $result = FOO() * FOO();
] or die $@;
并产生这些结果,
RssAnon: 75112 kB
RssFile: 5284 kB
RssShmem: 0 kB
和constant.pm
,
这可以进一步实现为,
eval qq[
our sub FOO ();
use constant FOO => 42;
package Foo$num;
my $result = FOO() * FOO();
];
这将产生这些结果,
RssAnon: 75076 kB
RssFile: 5180 kB
RssShmem: 0 kB