Thread Array ist nicht Array?!?: Was ist eigentlich ein Array in Perl? (23 answers)
Opened by highlander at 2006-04-07 17:02

murphy
 2006-04-09 19:40
#64551 #64551
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
- Selbst wenn das Array zunächst leer ist und du eine Menge Elemente mit push anfügst muss das Array nicht jedesmal kopiert werden, denn zum einen wird das Array vermutlich sinnvollerweise exponentiell vergrößert (also jedesmal, wenn das Ding voll ist, multipliziert man den reservierten Platz mit einem konstanten Faktor) und zum anderen ist der Speicherallokator des Systemes oder von Perl gewiss so ausgelegt, dass er Speicherblöcke bis zu einem gewissen Grad vergrößern kann, ohne zu kopieren.

- es gibt in Perl keinen "Pointer", der angibt, an welcher Stelle im Array etwas eingefügt werden soll, wenn man push benutzt. push hängt immer hinten an und unshift immer vorne.

- Eine Zuweisung zu $#array macht in der Tat zusammen mit push oder unshift wenig Sinn. Zusammen mit einer Zuweisung im Listenkontext noch weniger.

Ich habe bei mir mal folgendes Benchmark laufen lassen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
use strict;
use warnings;

use Benchmark qw/cmpthese/;

my $runs = 1024;
my $elts = 1024;

sub getsome {
return 0 .. $elts-1;
}

cmpthese(
$runs,
{
'push $' => sub {
my @ray = ();
push @ray, $_ for (0 .. $elts-1);
},
'push @' => sub {
my @ray = ();
push @ray, getsome();
},
'assign $' => sub {
my @ray = ();
$ray[$_] = $_ for (0 .. $elts-1);
},
'assign @' => sub {
my @ray = getsome();
},
'p assign $' => sub {
my @ray = ();
$#ray = $elts + $[ - 1;
$ray[$_] = $_ for (0 .. $elts-1);
}
});


Und das Resultat sieht so aus:
            Rate p assign $   assign $     push $     push @   assign @
p assign $ 1014/s         --        -4%       -12%       -29%       -30%
assign $   1056/s         4%         --        -8%       -26%       -27%
push $     1151/s        13%         9%         --       -19%       -20%
push @     1422/s        40%        35%        24%         --        -1%
assign @   1442/s        42%        37%        25%         1%         --


Das entspricht nicht so recht deinen Ergebnissen aber eher meinen Erwartungen (deine Messungen sind vielleicht nicht so gut vergleichbar, weil du immer noch die Zeit misst, die Split benötigt um den String auseinanderzunehmen).

Ich hätte allerdings gedacht, dass die Präallokation das ganze nicht noch verlangsamen sollte -- vielleicht spielt da noch Overhead von der Referenzzählung hinein, wenn man die Arrayelemente neu beschreibt.
When C++ is your hammer, every problem looks like your thumb.

View full thread Array ist nicht Array?!?: Was ist eigentlich ein Array in Perl?