in reply to array overhead

$a=[@$a] can be used to shrink the array. (Well, create a new one the minimal size.)

$ perl -MDevel::Peek -e'push @$a, $_ for qw( a b c d e ); Dump($a,1); +$a=[@$a]; Dump($a,1);' SV = IV(0x817bc44) at 0x817bc48 REFCNT = 1 FLAGS = (ROK) RV = 0x816c158 SV = PVAV(0x816d1c8) at 0x816c158 REFCNT = 1 FLAGS = () ARRAY = 0x8177928 FILL = 4 <----- 5 visible elements MAX = 11 <----- 12 elements allocated ARYLEN = 0x0 FLAGS = (REAL) SV = IV(0x817bc44) at 0x817bc48 REFCNT = 1 FLAGS = (ROK) RV = 0x816cea8 SV = PVAV(0x816d1dc) at 0x816cea8 REFCNT = 1 FLAGS = () ARRAY = 0x8183cb8 FILL = 4 <----- 5 visible elements MAX = 4 <----- 5 elements allocated ARYLEN = 0x0 FLAGS = (REAL)

But you might only end up fragmenting your memory, leaving less usable free memory behind.

Replies are listed 'Best First'.
Re^2: array overhead
by dave_the_m (Monsignor) on Jan 06, 2011 at 00:15 UTC
    Yeah, 232 byes is a lot of overhead for an array. My back-of-the envelope calculations show a clean, minimal array should have an overhead of about 60 bytes on a 32-bit system, so that shrinking should make a difference. I doubt that fragmentation will be an issue. The OP probably wants to shrink the SV holding the integer value too, since it appears to be 56 bytes, so probably still holds a string too ($a[5] = int $[a5] should do it).

    Dave.

      Assigning a number to a scalar doesn't free the string buffer, it just marks it as unused. You "solution" can actually increase the memory used.

      $ perl -MDevel::Size=total_size -E' $a[5]="5678"; say total_size($a[5]); $x=int($a[5]); say total_size($a[5]); ' 40 44

      undef $s (but not $s = undef;) will free the string buffer.

      $ perl -MDevel::Size=total_size -E' $a[5]="5678"; say total_size($a[5]); $t=int($a[5]); undef $a[5]; $a[5]=$t; say total_size($a[5]); ' 40 36

      It doesn't downgrade the scalar from PVIV to IV, though. You'd need to start with a new scalar to do that.

      $ perl -MDevel::Peek -MDevel::Size=total_size -E' $a[5]="5678"; say total_size($a[5]); $t=int($a[5]); delete $a[5]; $a[5]=$t; say total_size($a[5]); ' 40 16
        Yeah sorry, bad example.

        I was thinking in terms of using it within in your $a=[@$a], e.g. $a= [ @$a[0..4], int($a->[5]) ], where it *would* get a new SV.

        Dave.