Hast du schonmal mit Benchmarks rumgespielt?
Ich würde das gerne mal testen. Kennst du eine gute Doku ausser der
Manpage?
Eigentlich reicht die.
Hier mal der vergleich mit DB_File vs. Indexdatei
Wobei ich den code ein bisschen geändert habe, da so die Index datei immer neu eingelesen wird.
Das Ergebniss bei mir mit 10,000 aufrufen:
Benchmark: timing 10000 iterations of DB_File, idx File...
DB_File: 3 wallclock secs ( 2.36 usr + 0.00 sys = 2.36 CPU) @ 4237.29/s (n
=10000)
idx File: 6 wallclock secs ( 5.55 usr + 0.00 sys = 5.55 CPU) @ 1801.80/s (n
=10000)
Rate idx File DB_File
idx File 1802/s -- -57%
DB_File 4237/s 135% --
DB_File ist viel schneller
#!/usr/perl/bin -w
use strict;
package idx_datei;
# usage: build_index(*DATA_HANDLE, *INDEX_HANDLE)
sub build_index
{
my $data_file = shift;
my $index_file = shift;
my $offset = 0;
while (<$data_file>)
{
print $index_file pack("N", $offset);
$offset = tell($data_file);
}
}
# usage: line_with_index(*DATA_HANDLE, *INDEX_HANDLE, $LINE_NUMBER)
# returns line or undef if LINE_NUMBER was out of range
my $entry;
sub line_with_index
{
my $data_file = shift;
my $index_file = shift;
my $line_number = shift;
unless($entry)
{
my $size = length(pack("N", 0));
my $i_offset = $size * ($line_number-1);
seek($index_file, $i_offset, 0) or return;
read($index_file, $entry, $size);
}
my $d_offset = unpack("N", $entry);
seek($data_file, $d_offset, 0);
return scalar(<$data_file>);
}
package main;
use Benchmark;
my $lines = 100;
# idx File
my $file = 'file_idx.txt';
createfile();
open(FILE, "< $file") or die "Can't open $file for reading: $!\n";
open(INDEX, "+> $file.idx")
or die "Can't open $file.idx for read/write: $!\n";
idx_datei::build_index(*FILE, *INDEX);
# DB_File
use DB_File;
use Fcntl;
my $db_file = 'file_db.db';
my @lines;
my $tie = tie(@lines, "DB_File", $db_file, O_RDWR | O_CREAT, 0666, $DB_RECNO)
or die "Cannot open file $db_file: $!\n";
create_db_file();
# Vergleich
my $line;
Benchmark::cmpthese( 10000, {
'idx File' => sub { $line = idx_datei::line_with_index(*FILE, *INDEX, int(rand() * $lines )); },
'DB_File' => sub { $line = $lines[int(rand() * $lines)]; }
});
sub createfile
{
open(FILE, ">$file");
print FILE "$_.". ( 'x' x (rand()*80) ). "\n" for(0...$lines);
close FILE;
}
sub create_db_file
{
$lines[$_] = "$_.". ( 'x' x (rand()*80) ). "\n" for(0...$lines);
}
Struppi.