Использование undef, поскольку значения хэш-функции сохраняют память в Perl?

Идиома Perl для удаления дубликата оценивает от массива:

@uniq = keys %{{map{$_=>1}@list}} 

Это более дешевый для использования этой версии:

@uniq = keys %{{map{$_=>undef}@list}}

Я протестировал его с этими остротами и кажусь, что это верно на некоторых версиях 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 $$"'
6
задан brian d foy 25 January 2010 в 17:58
поделиться

1 ответ

Ну, undef должен быть значением излучения, означающая, что все ссылки на него указывают на ту же датум. Вы не получаете это для других литералов. Вам все еще нужен накладные расходы слота, который ссылается на это, хотя. Тем не менее, я не вижу его сохранить любую память для меня на Perl 5.10 или 5.11 на Mac OS X. Пока Perl может не использовать больше памяти в Nondef , если дело Он ожидает использования большего количества памяти, поэтому он все равно его хватает. Тем не менее, я не хочу расследовать использование памяти во внутренних органах прямо сейчас.

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 );

сначала выходит немного страшно, но вы видите, что значения 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 = ()
8
ответ дан 16 December 2019 в 21:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: