Der Speicherbedarf von einzelnen Perl-Variablen und komplexeren
Datenstrukturen lässt sich mit
Devel::Size
ermitteln. Hier die Werte für Perl 5.10 auf einem 32-Bit System.
(Eine andere Betrachtung - Messung des verbrauchten virtuellen
Speichers bei großen Datenstrukturen - hat Peter J. Holzer angestellt:
http://www.hjp.at/programming/perl/memory/)
Skalare
Skalar ohne Wert: |
16 Bytes |
Referenz: |
16 Bytes |
Integer: |
16 Bytes |
Float: |
24 Bytes |
Leerstring: |
36 Bytes |
String der Länge n: |
36+n Bytes |
Perl alloziert bei Strings jeweils 4 Bytes im Voraus, vermutlich um
jedes UTF-8 Zeichen speichern zu können. Obige Berechnung geht von
1-Byte-Zeichen aus. Enthält der String UTF-8 Zeichen mit 2, 3 oder 4
Byte, vergrößert sich der Platzbedarf entsprechend.
Arrays
leeres Array: |
100 Bytes |
Array der Größe n: |
100+4*n Bytes |
Perl vergrößert ein Array schrittweise auf 4, 8, 16, 32, 64,
... Elemente. D.h. wird das 4. Element zugewiesen, vergößert Perl
intern schon auf 8 Elemente usw. Für jedes Element alloziert Perl
einen Pointer (4 Bytes). Die angegebene Größe ist der
Netto-Speicherbedarf des Array, d.h. der Speicherbedarf der
(skalaren) Werte kommt noch hinzu.
Hashes
leerer Hash: |
76 Bytes |
Hash mit n Keys: |
ungefähr 76+n*4+n*(durchschn. Keygröße+8+Anz. Buckets) |
Perl vergrößert einen Hash schrittweise auf 8, 16, 32, 64,
... Elemente. D.h. wird das 8. Element zugewiesen, vergößert Perl
intern auf 16 Elemente usw. Für jeden Key alloziert Perl vorab einen
Pointer (4 Bytes). Zusätzlich kommt mit zunehmender Anzahl Buckets ein
wachsender Overhead von 9, 10, 11, ... Bytes je Key hinzu. Die Größe
des Key geht auch mit ein. Bei der Messung unten ist der Key der
String "EintragNNNN", also 11 Zeichen lang. Die angegebene Größe ist
der Netto-Speicherbedarf des Hash, d.h. der Speicherbedarf der
Werte kommt noch hinzu.
Messung
Perl Version: 5.026000
Skalar ohne Wert: 24 Bytes
Referenz: 24 Bytes
Integer: 24 Bytes
Float: 24 Bytes
String - leer: 42 Bytes
String - 1 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 2 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 3 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 4 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 5 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 6 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 7 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 8 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 9 1-Byte Zeichen: 42 Bytes (Diff: 0)
String - 10 1-Byte Zeichen: 48 Bytes (Diff: 6)
String - 11 1-Byte Zeichen: 48 Bytes (Diff: 0)
String - 12 1-Byte Zeichen: 48 Bytes (Diff: 0)
String - 16 1-Byte Zeichen: 56 Bytes (Diff: 8)
String - 20 1-Byte Zeichen: 56 Bytes (Diff: 0)
Array - leer: 64 Bytes
Array - 4 Elemente: 96 Bytes (Diff: 32) - 24.0 Bytes/Key
Array - 8 Elemente: 128 Bytes (Diff: 32) - 16.0 Bytes/Key
Array - 16 Elemente: 200 Bytes (Diff: 72) - 12.5 Bytes/Key
Array - 32 Elemente: 344 Bytes (Diff: 144) - 10.8 Bytes/Key
Array - 64 Elemente: 624 Bytes (Diff: 280) - 9.8 Bytes/Key
Hash - leer: 120 Bytes
Hash - 4 Keys: 396 Bytes (Diff: 276) - 99.0 Bytes/Key
Hash - 8 Keys: 736 Bytes (Diff: 340) - 92.0 Bytes/Key
Hash - 16 Keys: 1416 Bytes (Diff: 680) - 88.5 Bytes/Key
Hash - 32 Keys: 2776 Bytes (Diff: 1360) - 86.8 Bytes/Key
Hash - 64 Keys: 5496 Bytes (Diff: 2720) - 85.9 Bytes/Key
Hash - 128 Keys: 10936 Bytes (Diff: 5440) - 85.4 Bytes/Key
Hash - 256 Keys: 21872 Bytes (Diff: 10936) - 85.4 Bytes/Key
Hash - 512 Keys: 43632 Bytes (Diff: 21760) - 85.2 Bytes/Key
Hash - 1024 Keys: 87152 Bytes (Diff: 43520) - 85.1 Bytes/Key
Programm
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 use Devel::Size;
7
8 print "Perl Version: $]\n";
9
10 my $s1;
11 print 'Skalar ohne Wert: ',Devel::Size::size(\$s1)," Bytes\n";
12
13 my $s2 = \$s1;
14 print 'Referenz: ',Devel::Size::size(\$s2)," Bytes\n";
15
16 my $s3 = 4711;
17 print 'Integer: ',Devel::Size::size(\$s3)," Bytes\n";
18
19 my $s4 = 1234.567;
20 print 'Float: ',Devel::Size::size(\$s4)," Bytes\n";
21
22 my $s5 = '';
23 my $nLast = Devel::Size::size(\$s5);
24 print "String - leer: $nLast Bytes\n";
25
26 for my $i (1..12,16,20) {
27 $s5 = 'x'x$i;
28 my $n = Devel::Size::size(\$s5);
29 print "String - $i 1-Byte Zeichen: $n Bytes (Diff: ",$n-$nLast,")\n";
30 $nLast = $n;
31 }
32
33 my @a1;
34 $nLast = Devel::Size::size(\@a1);
35 print "Array - leer: $nLast Bytes\n";
36
37 for my $i (4,8,16,32,64) {
38 my @a2 = (1..$i);
39 my $n = Devel::Size::size(\@a2);
40 my $diff = $n-$nLast;
41 my $avg = $n/$i;
42 printf "Array - $i Elemente: $n Bytes (Diff: $diff) - %.1f Bytes/Key\n",
43 $avg;
44 $nLast = $n;
45 }
46
47 my %h1;
48 $nLast = Devel::Size::size(\%h1);
49 print "Hash - leer: $nLast Bytes\n";
50
51 for my $i (4,8,16,32,64,128,256,512,1024) {
52 my %h2;
53 for (my $j = 1; $j <= $i; $j++) {
54 $h2{sprintf 'Eintrag%04d',$j} = $j;
55 }
56 # @h2{(1..$i)} = (1..$i);
57 my $n = Devel::Size::size(\%h2);
58 my $diff = $n-$nLast;
59 my $avg = $n/$i;
60 printf "Hash - $i Keys: $n Bytes (Diff: $diff) - %.1f Bytes/Key\n",$avg;
61 $nLast = $n;
62 }
63
64 # eof