Struppi: Pointer ans Ende der Datei setzen mit seek

Beitrag lesen

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.