Schrift
[thread]6514[/thread]

grosse (1GB) binäre Dateien komplett auswerten



<< >> 9 Einträge, 1 Seite
Gast Gast
 2004-08-19 13:07
#49414 #49414
Hi,

habe ZeitPerformance-Problem mit folgendem Code

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
####################Anfang##############
#!/usr/local/bin/perl

use strict;

################################################################################
#Initialisierung
my (@botschaften_gesamt);

################################################################################
#main-Routine
print "\n\n ----------- Start --------- \n\n";

read_in();
process();

print "\n\n ----------- Ende  --------- \n\n";

################################################################################
sub read_in
{
   my ($botschaft_bin) = "\x00" x 16;
   my ($path_in) = shift @ARGV;

   open (FILE, "$path_in") or die $!;
   binmode (FILE);

   #es genügt den Cursor einmal in der Datei zu setzen
   seek (FILE, 1024, 0);

   until (substr($botschaft_bin,0,5) eq "\xFF" x 5 &&    $botschaft_bin ne "\xFF" x 16)
{

       ######################################################################
  #Einlesen einer Botschaft des cco.files -> i.O.
    read (FILE, $botschaft_bin, 16);

  ######################################################################
  #in der Botschaftsstruktur abspeichern
       push (@botschaften_gesamt, $botschaft_bin);

  }
close (FILE);
}
################################################################################
sub process
{
   my (@botschaft_process);

   #print
   mkdir "./result";
open Gelb, ">./result/gelb01.asc"; open Gruen, ">./result/gruen01.asc"; open Blau, ">./result/blau01.asc";
   
my ($kanal);
   my (%hash) = ("01",*Gelb , "02",*Gruen , "04",*Blau);


foreach (@botschaften_gesamt)
{
       #binäre Darstellung in hexadezimale wandeln
    $_ = unpack ("H32", $_);

    #Botschaft in ihre Elemente mittels unpack zerlegen
@botschaft_process = unpack("A10 A2 A20", $_);

    #alle CAN-Kanaele können durchlaufen werden
       foreach $kanal(keys(%hash))
       {
        if ($botschaft_process[1] eq $kanal)
        {
               printf {$hash{$kanal}} " %16s %1s  %20s \n", $botschaft_process[0],$botschaft_process[1],$botschaft_process[2];
            last;
        }
       }
       #Leeren des Feldes durch Freigeben des Elements
    $_ = undef;
   }
   close Gelb; close Gruen; close Blau;
}
######################################################Ende##########################


damit lese ich gesamte Datei in den Speicher (array) - 1.Mal komplett durch die Daten wandern
2.Mal wandern passiert bei Wandeln der binären Daten und nach Kriterium ausgeben an verschiedene FILEHANDLES

Wo liegt Potential zum beschleunigen???

Danke

Roger

Bearbeitet von Crian: CODE-Tags hinzugefügt\n\n

<!--EDIT|Crian|1092906861-->
ptk
 2004-08-19 13:31
#49415 #49415
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
1 GB? Wahrscheinlich kommst du an die Grenzen deines realen Speichers und der Rechner swappt wie wild. Vielleicht ist es besser, auf das Fuellen von @botschaften_gesamt zu verzichten und stattdessen gleich beim Einlesen die Ausgabedateien zu schreiben.

Kleiner Optimierungsvorschlag: statt
Code: (dl )
"\xFF" x 5
bei jedem Schleifendurchlauf zu erzeugen, solltest du lieber eine Konstante anlegen.
rookie
 2004-08-19 13:56
#49416 #49416
User since
2004-07-28
9 Artikel
BenutzerIn
[default_avatar]
kann ich diesen realen Speicher (damit meinst du einen teil des Arbeitsspeichers?!) abfragen und mein array danach füllen?
ptk
 2004-08-19 14:26
#49417 #49417
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Schwierig... die Speicherverwaltung laueft mehr oder weniger transparent fuer den Benutzer ab. Du kannst unter Linux beispielsweise die Werte mit
Code: (dl )
cat /proc/meminfo
ansehen. Dann musst du den Speicherverbrauch von Array-Elementen abschaetzen. Das kann man beispielsweise mit Devel::Size machen.
rookie
 2004-08-19 14:40
#49418 #49418
User since
2004-07-28
9 Artikel
BenutzerIn
[default_avatar]
ok und wo fin ich dazu nähere infos - im cpan

sowas schon mal gemacht? Code bsp.?
Ishka
 2004-08-19 15:28
#49419 #49419
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
wenn du wirklich durchläufst, dh. nicht rumspringen mußt, würde ich sie wirklich zweimal lesen und nicht im Speicher behalten, denn

a) wohl viel weniger Aufwand als alle Spezialfälle zu berücksichtigen
b) Es werden keine Daten rausgeswapt

@Konstannte anlegen - das macht der perl-optimierer schon automatisch - alles was vorab berechnet werden kann, wird berechnet.
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
ptk
 2004-08-19 16:45
#49420 #49420
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
@rookie: Nochmal meine Frage: brauchst du @botschaften_gesamt tatsaechlich? Kannst du nicht alles in einer Schleife erledigen? Und das Swappen war nur meine Vermutung, kannst du das auch bestaetigen? Wieviel Speicher hat der Rechner, was zeigt top oder ps waehrend des Ablaufs an? Ist das ueberhaupt eine Sache, die einmalig durchlaeuft, dann lohnt sich ein Feintuning gar nicht? Kannst du vielleicht auf eine "richtige" Datenbank umsteigen?
rookie
 2004-08-20 16:23
#49421 #49421
User since
2004-07-28
9 Artikel
BenutzerIn
[default_avatar]
ich benötige das skript häufiger - will es auf einem server clients zugängig machen - deswegen ist mir die zeit wichtig -- ich benötige nicht zwingend alle daten, je nach Useroption fällt ein Teil weg - aber ich muss alle auf diese Option hin analysieren -- ich dachte immer man schreibt so wenig wie möglich Code in einem geöffnetem Filehandle - deswegen Einlesen - Feld durchlaufen und Bearbeiten im RAM - und Auslesen (also eigentlich drei Durchläufe) -- das Testskript läuft bei mir noch unter Windows, deswegen "top"?? =/=)

--- Datenbank? ist der Zugriff den schneller - benötige Daten aus dem Quellfile in der Regel nur einmal zur Analyse, deswegen ist Datenbank doch zu großer Aufwand, oder??
ptk
 2004-08-20 18:35
#49422 #49422
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=rookie,20.08.2004, 14:23]ich benötige das skript häufiger - will es auf einem server clients zugängig machen - deswegen ist mir die zeit wichtig -- ich benötige nicht zwingend alle daten, je nach Useroption fällt ein Teil weg - aber ich muss alle auf diese Option hin analysieren -- ich dachte immer man schreibt so wenig wie möglich Code in einem geöffnetem Filehandle - deswegen Einlesen - Feld durchlaufen und Bearbeiten im RAM - und Auslesen (also eigentlich drei Durchläufe)
[/quote]
Hast du es mal ausprobiert, also ohne Zwischenarray?

Quote
-- das Testskript läuft bei mir noch unter Windows, deswegen "top"?? =/=)

--- Datenbank? ist der Zugriff den schneller - benötige Daten aus dem Quellfile in der Regel nur einmal zur Analyse, deswegen ist Datenbank doch zu großer Aufwand, oder??

Datenbanken duerften langsamer sein als selbst geschriebener handoptimierter Code. Allerdings wird es kompliziert, wenn du die Speicherverwaltung selbst in die Hand nehmen musst, das nimmt dir eine Datenbank ab. Es muss auch keine SQL-Datenbank sein, vielleicht geht ja etwas in Richtung Berkeley-DB.
<< >> 9 Einträge, 1 Seite



View all threads created 2004-08-19 13:07.