Quelle est la meilleure façon de gunzip fichiers avec Perl?
Est-il une solution plus rapide que mon 'zcat solution à gunzip fichiers avec Perl?
Un petit indice:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use IO::Uncompress::Gunzip qw(gunzip);
my $re = qr/test/;
my $bench = timethese($ARGV[1], {
zcat => sub {
if (defined open(my $FILE, "-|", "zcat " . $ARGV[0]))
{
while (<$FILE>)
{
print $_ if ($_ =~ $re);
}
close($FILE);
}
},
io_gunzip => sub {
my $z = new IO::Uncompress::Gunzip $ARGV[0];
while (<$z>)
{
print $_ if ($_ =~ $re);
}
},
io_gunzip_getline => sub {
my $z = new IO::Uncompress::Gunzip $ARGV[0];
while (my $line = $z->getline())
{
print $line if ($line =~ $re);
}
},
} );
cmpthese $bench;
1;
me donner ces résultats:
# zcat test.gz|wc -l
566
# zcat test2.gz|wc -l
60459
# ./zip_test.pl test.gz 500
Benchmark: timing 500 iterations of io_gunzip, io_gunzip_getline, zcat...
io_gunzip: 4 wallclock secs ( 3.01 usr + 0.01 sys = 3.02 CPU) @ 165.56/s (n=500)
io_gunzip_getline: 3 wallclock secs ( 2.58 usr + 0.03 sys = 2.61 CPU) @ 191.57/s (n=500)
zcat: 2 wallclock secs ( 0.20 usr 0.34 sys + 0.55 cusr 1.10 csys = 2.19 CPU) @ 228.31/s (n=500)
Rate io_gunzip io_gunzip_getline zcat
io_gunzip 166/s -- -14% -27%
io_gunzip_getline 192/s 16% -- -16%
zcat 228/s 38% 19% --
# ./zip_test.pl test2.gz 50
Benchmark: timing 50 iterations of io_gunzip, io_gunzip_getline, zcat...
io_gunzip: 31 wallclock secs (29.67 usr + 0.11 sys = 29.78 CPU) @ 1.68/s (n=50)
io_gunzip_getline: 26 wallclock secs (24.86 usr + 0.04 sys = 24.90 CPU) @ 2.01/s (n=50)
zcat: 5 wallclock secs ( 2.42 usr 0.19 sys + 1.19 cusr 0.27 csys = 4.07 CPU) @ 12.29/s (n=50)
Rate io_gunzip io_gunzip_getline zcat
io_gunzip 1.68/s -- -16% -86%
io_gunzip_getline 2.01/s 20% -- -84%
zcat 12.3/s 632% 512% --
Et aussi, je ne comprends pas pourquoi "while (<$z>)
" est plus lent que "while (my $line = $z->getline())
"...
- regarde sur le cpan.org - thereis probablement un module pour ce faire.
- comme IO::Uncompress::Gunzip ?
- J'ai écrit ce commentaire sur mon téléphone portable donc je n'ai pas les moyens de chercher et d'écrire une vraie réponse, mais cela ne sonne comme un candidat probable.
- Votre question est beaucoup moins général que votre titre ne l'indique. Vous souhaitez laisser l'original des fichiers non compressés et fonctionne sur l'ensemble du non compressé contenu (dans ce cas avec une regex). C'est beaucoup plus spécifique à la question de "Quelle est la meilleure façon de gunzip fichiers avec Perl?".
Vous devez vous connecter pour publier un commentaire.
Sur de bureau type de matériel, le zcat est tout, mais certains d'être I/O limitée sur le non-trivial de données (vos fichiers d'exemple sont terriblement banal, ils vont être mis en mémoire tampon pour être sûr), auquel cas il n'y a pas de code de niveau d'optimisation qui va travailler pour vous. La ponte externe gzip semble parfait pour moi.
J'ai mis à jour mon indice de référence avec PerlIO::gzip comme runrig suggéré.
Mon jour de référence:
Nouveaux résultats:
PerlIO::gzip est la solution la plus rapide !
Parce que
$z
est une auto objet lié, attaché objets sont notoirement lent, et<$z>
utilise l'attaché interface d'un objet à l'appelgetline()
plutôt que directement à l'appel de la méthode.Vous pouvez également essayer PerlIO-gzip mais je le soupçonne de ne pas être tout/beaucoup plus rapide que l'autre module.
La dernière fois que j'ai essayé, le frai externe
gunzip
a été beaucoup plus rapide que d'utiliser un module Perl (tout comme tes repères show). Je soupçonne que c'est tous les appels de méthode impliqués dans la liaison de la un descripteur de fichier.J'attends
<$z>
est plus lent que$z->getline
pour une raison similaire. Il n'y a plus de magie impliqués dans la compréhension que la première doit être traduit dans la seconde.