grosse Datei einlesen und weiterverarbeiten dauert lange

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
marlob
User
Beiträge: 51
Registriert: Mittwoch 23. August 2006, 20:13

Hallo,

ich habe eine 25 MB grosse Textdatei die ich nach bestimmten Funktionsaufrufen durchsuchen möchte. Die Ergebnisse schreibe ich dann mit xlwt in eine Exceldatei.
Dazu habe ich ein Beispiel von xlwt angepasst.
Den Code habe ich hier online gesetzt
http://pastebin.com/nXZwXYJa

Jetzt dauert die Ausführung des Skriptes ca 460 Sekunden. Meine Frage ist nun ob ich am Code was optimieren kann, damit er schneller ausgeführt wird?
Hier das Ergebnis vom Aufruf mit cProfile
http://pastebin.com/5Ld2FuDF
gruss
marlob
-------------------------------------
Linux Mint 17 + Python 2.7.6
marlob
User
Beiträge: 51
Registriert: Mittwoch 23. August 2006, 20:13

Hier noch ein Link zu der Textdatei die ich einlesen möchte
http://dl.dropbox.com/u/7063475/m7110426_baitt.zip
gruss
marlob
-------------------------------------
Linux Mint 17 + Python 2.7.6
BlackJack

@marlob: Am meisten Zeit frisst anscheinend der Parser. Die Funktion läuft 459 Sekunden. Die `parse()`-Funktion nimmt davon 454 Sekunden in Anspruch. Das Schreiben in das Arbeitsblatt insgesamt nur eine Zehntelsekunde:

Code: Alles auswählen

        1    3.514    3.514  459.841  459.841 write_xls.py:11(write_xls)
   591185    1.405    0.000  454.486    0.001 config.py:853(parse)
     3900    0.004    0.000    0.100    0.000 Worksheet.py:1002(write)
Vielleicht solltest Du mal einen anderen Parser ausprobieren. Oder vielleicht reicht es ja auch schon mit ganz einfachen Mitteln zumindest mal zu prüfen ob die Zeile mit Leerzeichen und 'call' beginnt, bevor Du sie parst. Denn die überwiegende Mehrzahl der Zeilen scheint ja nicht auf das Muster zu passen.
BlackJack

@marlob: Dein Programm lief bei mir fast 13 Minuten. Nachdem ich `lepl` durch `pyparsing` ersetzt habe, lief es in 13 Sekunden durch. Und die Änderungen dafür sind nicht so besonders gross gewesen:

Code: Alles auswählen

import pyparsing as pp
# ...
    number = pp.Regex(
        r'[\+\-]?(?:[0-9]*\.[0-9]+|[0-9]+\.|[0-9]+)(?:[eE][\+\-]?[0-9]+)?'
    )
    calls = pp.Suppress('call')
    string = pp.QuotedString('"', '\\')
    fctmmi = (
        calls + pp.Regex(r'\w+') + pp.Suppress('(') + string
        + pp.Suppress(',') + string + pp.Suppress(',') + number
        + pp.Suppress(')')
    )
# ...
                try:
                    result = fctmmi.parseString(decline)
                    # print result
                    rowx += 1
                    for colx, value in enumerate(result):
                        sheet.write(rowx, colx, value, data_xfs[colx])
                except pp.ParseException:
                    pass
Den regulären Ausdruck für Zahlen habe ich aus `lepl` kopiert.
marlob
User
Beiträge: 51
Registriert: Mittwoch 23. August 2006, 20:13

@BlackJack
Ich habe deinen Vorschlag mal umgesetzt und der Unterschied ist schon bemerkenswert.
Vielen Dank für den Hinweis :D
gruss
marlob
-------------------------------------
Linux Mint 17 + Python 2.7.6
Antworten