bitmuncher
Senior-Nerd
Ich muss ziemlich grosse Datenmengen durchparsen und daraus spezifische Daten sammeln. Soweit mit Perl auch kein Problem, allerdings erreiche ich eine RAM-Benutzung von ca. 1,5GB, wenn ich die benötigten Daten in Hashes ablege. Das ist aufgrund des zu erwartenden Datenzuwachses (ca. das 100-fache in einem Jahr) absolut inakzeptabel und so suche ich nun schon seit geraumer Zeit eine Möglichkeit die Daten möglichst effizient zu nutzen. Da die Laufzeit auch so schon > 1 Stunde ist, scheidet das temporäre Ablegen der Daten auf der Festplatte aus, da damit die Laufzeit noch weiter verlängert wird. Langsam bin ich mit meinem Latein am Ende. Die in den Hashes abgelegten Daten sind primär Strings als Keys und Integer als Werte. Hat hier evtl. jemand eine Idee, wie ich die Daten möglichst einfach im RAM komprimiert ablegen kann ohne auf die Hashes verzichten zu müssen? Derzeit sieht das Parsen so aus:
Code:
...
foreach my $line (<INFILE>) {
if($line =~ /^http:\/\/([\w\.]*)\/.*\s->\s(.*)/) {
my $referer = $1;
my $script = $2;
if(exists($allstats{$referer})) {
$allstats{$referer} = ++$allstats{$referer};
} else {
$allstats{$referer} = 1;
}
if($script =~ '^/script1') {
if(exists($jsw_stat{$referer})) {
$jsw_stat{$referer} = ++$jsw_stat{$referer};
} else {
$jsw_stat{$referer} = 1;
}
} elsif($script =~ '^/script2') {
if(exists($tokstaim_stat{$referer})) {
$tokstaim_stat{$referer} = ++$tokstaim_stat{$referer};
} else {
$tokstaim_stat{$referer} = 1;
}
} else {
if(exists($other_stat{$referer})) {
$other_stat{$referer} = ++$other_stat{$referer};
} else {
$other_stat{$referer} = 1;
}
}
}
}
...
foreach my $line (<INFILE>) {
if($line =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s.*/) {
my $ip = $1;
print $ip."<br />\n";
if(exists($unique_stat{$ip})) {
$unique_stat{$ip} = ++$unique_stat{$ip};
} else {
$unique_stat{$ip} = 1;
}
}
}
...