用于从数组中删除重复值的Perl习惯用法:
@uniq = keys %{{map{$_=>1}@list}}
Run Code Online (Sandbox Code Playgroud)
使用这个版本更便宜:
@uniq = keys %{{map{$_=>undef}@list}}
Run Code Online (Sandbox Code Playgroud)
我用这些单行测试了它,似乎在某些版本的Perl上都是如此:
perl -e 'my %x; $x{$_} = 1 for 0..1000_000; system "ps -ovsz $$"'
perl -e 'my %x; $x{$_} = undef for 0..1000_000; system "ps -ovsz $$"'
Run Code Online (Sandbox Code Playgroud)
好吧,undef应该是一个flyweight值,这意味着对它的所有引用都指向相同的数据.你没有得到其他文字.您仍然需要引用它的插槽的开销.不过,我没有看到它保存任何记忆,我在Perl的5.10或5.11的Mac OS X.虽然perl可能不会在使用更多的内存undef的情况下,我敢打赌,它使用更多的内存,因此抓住它无论如何期待.但是,我现在并不热衷于调查内部的内存使用情况.
Devel :: Peek非常方便展示这些东西:
#!perl
use Devel::Peek;
my $a = undef;
my $b = undef;
Dump( $a );
Dump( $b );
my %hash = map { $_, undef } 1 .. 3;
$hash{4} = 'Hello';
Dump( \%hash );
Run Code Online (Sandbox Code Playgroud)
输出看起来有点可怕,但是你看到的是undef值NULL(0x0)而不是单个字符串值(PV):
SV = NULL(0x0) at 0x100208708
REFCNT = 1
FLAGS = (PADMY)
SV = NULL(0x0) at 0x100208738
REFCNT = 1
FLAGS = (PADMY)
SV = RV(0x100805018) at 0x100805008
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x100208780
SV = PVHV(0x100809ed8) at 0x100208780
REFCNT = 2
FLAGS = (PADMY,SHAREKEYS)
ARRAY = 0x100202200 (0:5, 1:2, 2:1)
hash quality = 91.7%
KEYS = 4
FILL = 3
MAX = 7
RITER = -1
EITER = 0x0
Elt "4" HASH = 0xb803eff9
SV = PV(0x100801c78) at 0x100804ed0
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x100202a30 "Hello"\0
CUR = 5
LEN = 8
Elt "1" HASH = 0x806b80c9
SV = NULL(0x0) at 0x100820db0
REFCNT = 1
FLAGS = ()
Elt "3" HASH = 0xa400c7f3
SV = NULL(0x0) at 0x100820df8
REFCNT = 1
FLAGS = ()
Run Code Online (Sandbox Code Playgroud)