#! perl -slw use strict; use constant { KEYLEN => 8, ALPHA => [ 'A'..'Z' ], CONDITION_FREQUENCY => 0.2, LIST_SIZE => 1e6, }; our $MAX ||= LIST_SIZE; sub rndStr{ join'', @_[ map{ rand @_ } 1 .. shift ] } sub property { rndStr( KEYLEN, @{+ALPHA} ) } sub condition_is_true{ rand() < CONDITION_FREQUENCY ? '1' : '0' } my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); my( $count, $flag ) = unpack 'Nc', $records{ $key }||pack('Nc', 0, 0 ); ++$count; $flag = 1 if condition_is_true( $item ); $records{ $key } = pack 'Nc', $count, $flag; } printf 'check Memory: '; ; __END__ ----------HOHs--------------- my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); ++$records{ $key }{ count }; if( condition_is_true( $item ) ) { $records{ $key }{ flag } = 1; } } c:\test>590773 -MAX=1e5 check Memory: 25 MB c:\test>590773 -MAX=1e6 check Memory: 240 MB c:\test>590773 -MAX=2e6 check Memory: 480 MB ----------HoAs-------------- use constant { FLAG => 0, COUNT => 1 }; my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); ++$records{ $key }[COUNT]; if( condition_is_true( $item ) ) { $records{ $key }[FLAG] = 1; } } c:\test>590773 -MAX=1e5 check Memory: 22 MB c:\test>590773 -MAX=1e6 check Memory: 210 MB c:\test>590773 -MAX=2e6 check Memory: 420 MB --------HoIVs--------- sub sgn{ ($_[ 0 ]||0 ) < 0 ? -1 : 1 } my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); $records{ $key } += sgn( $records{ $key } ); if( condition_is_true( $item ) ) { $records{ $key } = - $records{ $key }; } } c:\test>590773 -MAX=1e5 check Memory: 11 MB c:\test>590773 -MAX=1e6 check Memory: 90 MB c:\test>590773 -MAX=2e6 check Memory: 180 MB --------HoPVs(5 bytes)--------- my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); my( $count, $flag ) = unpack 'nc', $records{ $key }||pack('nc', 0, 0 ); ++$count; $flag = 1 if condition_is_true( $item ); $records{ $key } = pack 'nc', $count, $flag; } c:\test>590773 -MAX=1e5 check Memory: 15 MB c:\test>590773 -MAX=1e6 check Memory: 120 MB c:\test>590773 -MAX=2e6 check Memory: 245 MB --------HoPVs(9 bytes)--------- my %records; foreach my $item ( 1 .. $MAX ) { my $key = property($item); my( $count, $flag ) = unpack 'Nc', $records{ $key }||pack('Nc', 0, 0 ); ++$count; $flag = 1 if condition_is_true( $item ); $records{ $key } = pack 'Nc', $count, $flag; } c:\test>590773 -MAX=1e5 check Memory: 15 MB c:\test>590773 -MAX=1e6 check Memory: 129 MB c:\test>590773 -MAX=2e6 check Memory: 261 MB