Integer mit unpack auspacken

07/04/2011 - 21:14 von Erik Braun | Report spam
Hallo,

ich habe eine Reihe Datensàtze fester Breite, in denen Integerzahlen
stecken, welche ich mit unpack() extrahieren wollte, da substr() oder
s/// deutlich langsamer sein sollen. Leider versteht das unpack unter
Integer nicht ganz das, was man intuitiv darunter vermutet. In diesem
Beispiel hàtte ich die Ausgabe erwartet:

1234 6789
12346789

Tatsàchlich sieht sie so aus:

erik@debian:~$ perl
$string=' 1234 6789';
($a,$b)=unpack '@0 A8 @8 A8', $string;
print "$a$b";
($a,$b)=unpack '@0 I8 @8 I8', $string;
print "$a$b";
__DATA__
1234 6789
538976288875770417


Gibt es einen Weg, direkt mit unpack nur die Zahlen zu ermitteln, oder komme
ich nicht um ein int($a) o. à. herum?


Danke, Erik
 

Lesen sie die antworten

#1 Rafael Koeppen
07/04/2011 - 23:42 | Warnen spam
Hallo Erik,

folgender Code vergleicht 3 Möglichkeiten hinsichtlich der Performance.
Funktioniert nur, wenn die Datensàtze den Aufbau wie in deinem $string
haben:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use Benchmark qw(cmpthese);
cmpthese(100000,{a=>\&regex1,b=>\&replace1,c=>\&substr1});

# folgende 3 Zeilen auskommentiert, nur um die Ergebnisse der subs zu
prüfen:
#&regex1;
#&replace1;
#&substr1;

sub regex1 {
$string=' 1234 6789';
$string =~ /\s+(\d+)\s+(\d+)/ && print "$1$2";
}
sub replace1 {
$string=' 1234 6789';
$string =~ s/\s+//g;
print "$string";
}
sub substr1 {
$string=' 1234 6789';
$a = substr($string,4,4);
$b = substr($string,12,4);
print "$a$b";
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bei mir (6 Jahre alter AMD Athlon 3500 mit Win XP) sieht das Ergebnis
so aus:

Rate a b c
a 164474/s -- -13% -26%
b 188324/s 15% -- -15%
c 221239/s 35% 17% --

Heißt, die substr-Variante ist bezogen auf o.g. Vergleich die schnellste.
Allerdings wird der Großteil der Zeit durch die print-Statements
verbraucht (lass es mal mit auskommentierten prints laufen).
Von daher gesehen stellt sich die Frage, ob die "Langsamkeit" überhaupt
eine Rolle spielt ...

Gruß Rafael



Am 07.04.2011 21:14, schrieb Erik Braun:
Hallo,

ich habe eine Reihe Datensàtze fester Breite, in denen Integerzahlen
stecken, welche ich mit unpack() extrahieren wollte, da substr() oder
s/// deutlich langsamer sein sollen. Leider versteht das unpack unter
Integer nicht ganz das, was man intuitiv darunter vermutet. In diesem
Beispiel hàtte ich die Ausgabe erwartet:

1234 6789
12346789

Tatsàchlich sieht sie so aus:

:~$ perl
$string=' 1234 6789';
($a,$b)=unpack '@0 A8 @8 A8', $string;
print "$a$b";
($a,$b)=unpack '@0 I8 @8 I8', $string;
print "$a$b";
__DATA__
1234 6789
538976288875770417


Gibt es einen Weg, direkt mit unpack nur die Zahlen zu ermitteln, oder komme
ich nicht um ein int($a) o. à. herum?


Danke, Erik

Ähnliche fragen