Seite 1 von 1

RE und Python 2.5.2: Probleme beim Matching von > 2GB

Verfasst: Freitag 30. Oktober 2009, 10:48
von BastiL
Hallo zusammen,

ich match emit einem RE einen Bereich in einem File der größer als 2GB ist. Dann bekomme ich mit m.end für den Endindex einen negativen Wert, d.h irgend etwas läuft da über.... Da ich diesen Index brauche bin ich jetzt am überlegen, wie ich den anders bekommen könnte? Ideen sind willkommen.

Grüße

Verfasst: Freitag 30. Oktober 2009, 11:03
von Defnull
Dazu solltest du uns vielleicht verraten, was das für Daten sind und wie dein re bisher aus sieht? RE ist nützlich, man kann aber nicht alles damit machen.

Verfasst: Freitag 30. Oktober 2009, 12:19
von BastiL
Ich wollte eingentlich nicht alles umstellen. Gibt es denn eine andere Möglichkeit diesen Index zu bestimmen? Ist das möglicherweise in Python 2.6 oder später gefixt?

Verfasst: Freitag 30. Oktober 2009, 12:31
von CM
Defnull hat geschrieben:Dazu solltest du uns vielleicht verraten, was das für Daten sind und wie dein re bisher aus sieht?
Sorry, BastiL, aber Kristallkugeln sind nicht in der Python Standardlib.

Verfasst: Freitag 30. Oktober 2009, 12:36
von cofi
CM hat geschrieben:Sorry, BastiL, aber Kristallkugeln sind nicht in der Python Standardlib.
Die Batterien dafuer sind aber dabei! :twisted:
Vllt sollte man ein Aequivalent zu `antigravity` vorschlagen? 8)

Verfasst: Freitag 30. Oktober 2009, 13:00
von snafu
Ich dachte immer Kristallkugel wäre `chr()`. :o

Verfasst: Freitag 30. Oktober 2009, 13:22
von BastiL
Also: mein Re sieht so aus:

Code: Alles auswählen

ausdruck=re.compile(r'\(0 "Grid:"\).*(?s)(?=\(0 "Thread variables:"\))').search(File, re.I)
Die Daten sind vertraulich, aber das Schema ist dieses:

Einige MB
(0 "Grid:"
einige GB Daten
(0 "Thread variables:"
einige MB

Sofern der Bereich "einige GB" kleiner als 2GB ist läuft alles wie es soll. Ich versuche unter anderem, den Bereich ab (0 "Thread variables" bis zum Dateiende anzusprechen und verwende dazu

Code: Alles auswählen

ausdruck.end(0)
Dieser Ausdruck wird negativ, sobald einge GB > 2GB wird.... Ich denke das ist ein Python-internes Problem. Was ich schon versucht habe:

- Statt auf den Mittelteil der Datei auf das Ende zu matchen - dann wird das Suchen SEHRSEHR viel langsamer. Das will ich nicht.

Verfasst: Freitag 30. Oktober 2009, 14:03
von BlackJack
Wenn `n` die negative Zahl ist, kommt dann bei ``(-n ^ 0xffffffff) + 1`` der richtige Offset heraus? Dann wäre das zumindest schon einmal eine Notlösung.

Edit: Darf ich mal nach dem Sinn von `re` bei diesem simplen Ausdruck fragen? Da kann man doch auch mit `index()` bzw. `find()` arbeiten!?

Verfasst: Freitag 30. Oktober 2009, 14:44
von BastiL
BlackJack hat geschrieben:Wenn `n` die negative Zahl ist, kommt dann bei ``(-n ^ 0xffffffff) + 1`` der richtige Offset heraus? Dann wäre das zumindest schon einmal eine Notlösung.
Werde ich testen.
Edit: Darf ich mal nach dem Sinn von `re` bei diesem simplen Ausdruck fragen? Da kann man doch auch mit `index()` bzw. `find()` arbeiten!?
Ja - es geht bei der speziellen Struktur der Files so deutlich schneller. Der Teil "einige GB Daten" enthält Binärdaten die die Suche offensichtlich ganz erheblich ausbremsen. Wir reden hier von ein paar ms im Vergleichzu mehreren Minuten Dauer zum durchsuchen....

Verfasst: Freitag 30. Oktober 2009, 15:23
von pillmuncher
BlackJack hat geschrieben:Edit: Darf ich mal nach dem Sinn von `re` bei diesem simplen Ausdruck fragen? Da kann man doch auch mit `index()` bzw. `find()` arbeiten!?
Some people, when confronted with a problem,
think "I know, I'll use regular expressions."
Now they have two problems. -- Jamie Zawinski

[edit]
Ich gehör auch zu diesen Leuten. :oops:
[/edit]

Verfasst: Freitag 30. Oktober 2009, 17:29
von BlackJack
@BastiL: Also bei *dem* regulären Ausdruck kann eine Lösung mit `find()` nicht wirklich langsamer sein.

Verfasst: Freitag 30. Oktober 2009, 23:58
von BastiL
BlackJack hat geschrieben:@BastiL: Also bei *dem* regulären Ausdruck kann eine Lösung mit `find()` nicht wirklich langsamer sein.
Das dachte ich auch. Ich werde am Montag nochmal ein Benchmark fahren. Der reguläre Ausdruck ist für eine Datei dieser Größe einfach sensationell schnell..... Ich weiss auch nicht warum.

Verfasst: Samstag 31. Oktober 2009, 10:25
von sma
Es wundert mich überhaupt, dass Strings mit mehr als 2 GB Daten funktionieren. Ist das eine 64-Bit-Version von Python? Falls nein, würde ich empfehlen, eine solche zu benutzen, denn ich denke nicht, dass eine 32-Bit-Version mit 4-Byte-Integern über die 2**31-1-Grenze für Strings und ihre Indices kommen kann. Falls du kein 64-Bit-Betriebssystem hast, bleibt dir nur, das ganze in mehreren Teilen zu untersuchen.

Stefan

Verfasst: Samstag 31. Oktober 2009, 12:57
von BastiL
sma hat geschrieben:Es wundert mich überhaupt, dass Strings mit mehr als 2 GB Daten funktionieren. Ist das eine 64-Bit-Version von Python
Ja ist es 64 Bit Linux.

Verfasst: Montag 2. November 2009, 10:41
von BastiL
BlackJack hat geschrieben:Wenn `n` die negative Zahl ist, kommt dann bei ``(-n ^ 0xffffffff) + 1`` der richtige Offset heraus? Dann wäre das zumindest schon einmal eine Notlösung.
Das funktioniert so. Notlösung gefunden
Darf ich mal nach dem Sinn von `re` bei diesem simplen Ausdruck fragen? Da kann man doch auch mit `index()` bzw. `find()` arbeiten!?
Dabei ist das Problem, dass die Datei per mmap in den Hauptspeicher gelesen wird und damit offensichtlich kein String ist. Deshalb konnte ich gerade kein Benchmark zur Performencekontrolle fahren, um find() mit dem regEx zu vergleichen. Geht das irgendwie, ein mit mmap eingelesenes File mit find() zu bearbeiten?

Verfasst: Montag 2. November 2009, 13:31
von HWK
Vielleicht mit dem deprecated find aus dem String-Modul?

Code: Alles auswählen

string.find(mmap, substring)
MfG
HWK

Verfasst: Montag 2. November 2009, 13:47
von BastiL
Ich habe inzwischen festgestllt, das find() doch geht. rfind sollte laut mmap-Doku auch gehen tut bei mir aber nicht. Rindex und index gehen nicht, wie auch in der Doku beschrieben.
Die Suchzeit verändert sich für ein 3,7 GB-File von wenigen ms (mit regex) auf 12,4s mit find. Daher ist find für mich schlicht zu langsam und ich verwende die vorgeschlagene Notlösung.