Schnellste Verfahren um eine große Datei?
Ich habe mehrere 3-GB-tab-getrennte Dateien. Es gibt 20 Millionen Zeilen in jeder Datei. Alle Zeilen werden unabhängig voneinander verarbeitet, keine Beziehung zwischen zwei Zeilen.
Meine Frage ist, was schneller sein wird A. Lesen Zeile für Zeile mit:
with open() as infile:
for line in infile:
Oder B. das Lesen der Datei in den Speicher, in Stücke schneiden und verarbeiten es, sagen wir 250 MB auf einmal?
Die Verarbeitung ist nicht sehr kompliziert, ich bin nur grabbing Wert in Spalte 1 zu List1
, spalte2, um List2
etc. Vielleicht müssen Sie fügen Sie einige Werte in der Spalte zusammen.
Ich bin mit python 2.7 auf einer linux-box, die hat 30GB Speicher. ASCII-Text.
Irgendeiner Weise die Dinge zu beschleunigen parallel? Jetzt bin ich über das bisherige Verfahren und der Prozess ist sehr langsam. Ist mit jedem CSVReader
Modul gehen, um zu helfen?
Ich don ' T haben, es zu tun in python, einer anderen Sprache oder Datenbank verwenden Sie die Ideen sind willkommen.
- multiprocessing; chunked iterative Lesen. Bei 3 GB pro Datei, die Sie NICHT möchten, Lesen diese vollständig in den Speicher; Sie können Blasen Sie Ihre Speicher-Ressourcen.
- Es klingt wie eine Datenbank helfen würde, Sie aus je nach Art der Verarbeitung, die Sie tun.
- Nicht, wenn dies ist ein single-throw-away-Aufgabe; Daten; Verarbeitung; data-out; löschen von Quell-Daten.
- Ist dein code I/O-bound und CPU-bound? In anderen Worten, braucht die Verarbeitung mehr Zeit in Anspruch als das Lesen? Wenn dem so ist, kann man wohl die Geschwindigkeit, die es mit multiprocessing; wenn nicht, wird Ihre hintergrund-Prozesse sind einfach zu verbringen alle Ihre Zeit mit warten auf den nächsten zu Lesen und du wirst keinen nutzen.
- Haben Sie überprüft, ob Ihre Langsamkeit ist in der Verarbeitung oder im Lesen? Wie schnell ist es, wenn die einzige Sache in Ihrem
for
Schleife istpass
? Ohne zu prüfen, könnte man versuchen zu optimieren, die falsche Sache. - Macht einen sehr guten und klar auf den Punkt hier. Ihre Lösung wird abhängen, ob Ihr problem ist der I/O-oder CPU-gebunden. Obwohl auf den ersten Blick sieht es aus wie es sein könnte-I/O-bound 🙂
- Inzwischen
for line in infile:
schon anständige Pufferung innerhalb derio
code module (in Python 3.1+) oder in der C-stdio darunter (in Python 2.x), so, wenn Sie mit Python 3.0, sollte es in Ordnung sein. Aber wenn Sie wollen, zu zwingen, es zu verwenden, größere Puffer, Sie können die loop immer über, sagen wir,infile.readlines(65536)
und dann die Schleife über die Zeilen innerhalb jedes Stück. - Auch, dass es wohl einen großen Unterschied macht, ob das 2.x oder 3.x, die 3.x-version, wenn 3.x, auf welcher Plattform man sich befindet, und ob das ASCII-text oder etwas, dass wirklich erst entschlüsselt werden muss, so fügen Sie bitte diese Informationen.
- Bitte fügen Sie auch einige details über die Art der "Verarbeitung", die ausgeführt wird auf die Datensätze.
- am besten. wenn Sie/er hatte viel Speicher und habe keine sorgen über die 3GB Treffer, er/Sie könnte tun
for line in infile.readlines():
die viel schneller zu Durchlaufen als das file-Objekt selbst - vereinbart ist; vorausgesetzt, man verkraftet werden könnte, wie eine massive Treffer auf Speicher!!! Bare daran, dass dies nicht verbrauchen, 3GB Arbeitsspeicher, sondern viel viel mehr!
- Mit
readlines()
ist fast immer langsamer als Schleife überreadlines(bufsize)
mit einer großen, aber nicht 3GB Puffer, weil Sie nicht Lesen können, nicht schneller als einige maximale Größe in einer Zeit, so darüber hinaus, dass alle Sie tun ist das hinzufügen von unnötigen Speicherzuweisung an den mix-plus-VM-Seite findet. - Könnten Sie bitte zeigen Sie einige Ihrer code ", die die eigentliche Verarbeitung"? Vage über das, was es tut, ist das nicht hilfreich.
- ja, vergaß zu erwähnen, es ist mehr als ein 3Gb-Treffer, das ist ein wichtiger Punkt.. danke! so oder so, wir stecken fest zwischen einem Engpass der CPU, oder für einen Engpass, von Speicher, oder einen Engpass Zeit. welche Art von CPU ' s entwickeln wir für diese? wenn Sie dual-core, Teilprozesse nehmen einen ziemlich großen hit. wie groß ist die Anwendung/Programm dies ist? gibt es eine dire need for speed? sein Brutal ehrlich, wenn Sie wollen, eine Sprache, die "schnell", es ist nicht python...
- Tatsächlich habe ich persönlich hatte eine Menge Erfahrung im Umgang mit der Verarbeitung von "BIg Data" mit Python und Tarife ganz gut, wenn Sie entwerfen Sie Ihre Lösungen korrekt; wieder je nach der Natur des Problems der CPU vs. I/O-Gebunden oder ein bisschen von beidem. Python nicht wirklich so langsam 🙂
- Was anderen Sprache würden Sie vorschlagen, um zu versuchen, diese Arbeit? Dank
- Die Wahl der Sprache ist nicht wirklich dein problem hier; sondern, wie Sie verwalten I/O und wie Sie die übertragung der Arbeit (CPU-Gebunden-Teile).
- Nebenbei; wenn Python war unbrauchbar langsam an Big-Data-Analyse-Aufgaben geben; es würde noe, so weit verbreitet in der wissenschaftlichen Gemeinschaft und der verschiedenen Forschungs-Projekte 🙂
- Natürlich in der scientific community, Sie sind oft der Verarbeitung, die Dinge schräg, anstatt sequenziell, und es ist zulässig, zu sagen: "wir haben 18GB an Daten? dann lassen Sie uns 32GB RAM", denn nur mit anderen big-data nutzt, bist du nicht speccing, Dutzende von Servern, nur eine workstation... Aber Python ist auch in vielen big-data-server-Typ verwendet, auch, so Ihr Punkt ist definitiv gültig.
- welche anderen Sprachen kennt Ihr? sind Sie okay mit Programmiersprachen, die kompiliert werden (d.h. langsamer zu initialisieren)? etc... in Bezug auf die Schnellste, C, die eine Implementierung von python verwendet als zugrunde liegenden Mechanismus für die Sprache, C++ ist schneller, java ist wahrscheinlich schneller usw.. aber du redest niedrigeren Niveau Sprachen im Vergleich zu python
- Wäre C# zu arbeiten??
- zu Ihrem Kommentar davor: ja,
readlines()
ist langsamer, WENN der computer kann keine Zuordnung der erforderlichen Speicher für die es auf einmal, aber wenn wir reden darüber, dass Sie gerne 64Gb RAM, dann ist das ein non-Faktor. auch, wenn man oft die Verarbeitung Dinge parallel statt sequentiell (ich denke das meintest du?), dann wieder, werden Sie wahrscheinlich nicht wollen, python... - C# ist sehr ähnlich zu-Laufzeit/compile-time performance von Java. So wahrscheinlich. Die trade-off hier ist der ofc ist die Entwicklung Zeit-und compile-Zeit.
- Man könnte immer nur verwenden, PyPY, wie Ihre alternative Python-Implementierung hier; ABER dein problem ist, dass der I/O gebunden; nicht CPU-Gebunden, so PyPy ist unwahrscheinlich, dass die Dinge zu beschleunigen, dass viel, aber es wäre sicherlich schneller als CPython.
- piggy-backing off von JamesMills, ja, C# ist vergleichbar mit Java. Es wird ein langsamer Programm - /app-Initialisierung Zeit im Vergleich zu der python-app, aber Sie profitieren viel, sobald es läuft. Kompiliert vs. Interpretiert. Es ist auch härter und länger zu entwickeln. Aber es Griffe threading in wie, eine Welt, die besser von der Leistung als python, wie python ' s GIL ist ein deal breaker (halten Sie im Verstand, ich bin das diskutieren threading und nicht schnelles)
- Von der Rückseite des @ Vincenzzzochi Kommentar, Die Python GIL ist aber Weg in die PyPy-STM Implementierung, damit in der Zukunft hoffentlich können wir alle freuen uns auf eine Python-Implementierung mit besserer multi-threading 🙂
- Selbst wenn du 64 GB RAM,
readlines()
ist in der Regel immer noch langsamer als bei der Iteration überreadlines(bufsize)
, weil Sie noch brauchen, um malloc 12 GB statt 1 MB, und Sie können auch haben, um page-fault Millionen mal anstelle von 0. Auch, natürlich, Sie haben zu tun, alle I/O zuerst, dann alle die Verarbeitung, anstatt in der Lage pipeline für die zwei. Und das ist, abgesehen von der Tatsache, dass Ihre 64GB kann NUMA, während Ihre 1MB passen kann in einem lokalen cache, etc. - Ist der Vorteil von C# ist, dass Parallele.ForEach kann werden verwendet, um die Verarbeitung der Stücke zusammen, und damit Senkung der gesamten Laufzeit?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es klingt wie dein code E/A-gebunden. Dies bedeutet, dass multiprocessing ist nicht zu helfen—wenn Sie verbringen 90% Ihrer Zeit mit dem Lesen von der Festplatte, mit einem extra 7 Prozesse, die darauf warten, auf den nächsten zu Lesen ist nicht zu helfen, nichts.
Und, während der Verwendung einer CSV-lese-Modul (ob die stdlib ist
csv
oder so etwas wie NumPy oder Pandas) vielleicht eine gute Idee für Einfachheit, es ist unwahrscheinlich, dass viel Unterschied in der Leistung.Immer noch, lohnt es sich, zu prüfen, dass Sie wirklich sind I/O-gebunden ist, anstatt nur zu raten. Führen Sie das Programm und sehen, ob Ihre CPU-Auslastung nahe 0% oder nahe 100%, oder einen Kern. Tun, was Amadan schon in einem Kommentar angedeutet, und führen Sie Ihr Programm mit nur
pass
für die Verarbeitung und sehen, ob die Schnitte aus 5% der Zeit oder 70%. Sie möchten vielleicht sogar zu versuchen, zu vergleichen mit einer Schleife überos.open
undos.read(1024*1024)
oder etwas und sehen, ob das schneller.Seit Ihr mit Python 2.x, Python ist, sich auf die C-stdio-Bibliothek zu erraten, wie viel Puffer zu einer Zeit, so dass es sich lohnen könnte, zwingt Sie in den Puffer mehr. Die einfachste Möglichkeit hierzu ist die Verwendung
readlines(bufsize)
für einige großebufsize
. (Sie können versuchen, verschiedene Nummern und zu Messen, um zu sehen, wo der peak ist. In meiner Erfahrung in der Regel nichts von 64 KB-8 MB ist ungefähr das gleiche, aber je nach Ihrem system kann unterschiedlich sein—vor allem wenn man, z.B., das Lesen aus einem Netzwerk-Dateisystem mit großen Durchsatz, aber schreckliche Latenz, die Sümpfe der Durchsatz-vs. Latenz der eigentliche physische Laufwerk und das caching des OS funktioniert.)So, zum Beispiel:
Mittlerweile, wenn Sie auf einem 64-bit-system ist, möchten Sie vielleicht zu versuchen, mit
mmap
zu Lesen, anstatt die Datei in den ersten Platz. Dies ist sicherlich nicht garantiert besser, aber es kann besser sein, abhängig von Ihrem system. Zum Beispiel:Python
mmap
ist eine Art von einem seltsamen Objekt—es wirkt wie einstr
und wie einfile
zur gleichen Zeit, so können Sie, z.B., manuell Durchlaufen Scannen für Zeilenumbrüche, oder rufen Siereadline
auf, als wäre es eine Datei. Diese beiden nehmen eine weitere Verarbeitung von Python als Iteration die Datei als Zeilen-oder tut batch -readlines
(weil eine Schleife, die C ist jetzt in pure Python... obwohl, vielleicht kann man umgehen, mitre
oder mit einem einfachen Cython-Erweiterung?)... aber die I/O-Vorteil, den OS wissen, was Sie tun mit dem mapping kann Sumpf der CPU-Nachteil.Leider ist Python nicht aussetzen
madvise
nennen, die Sie verwenden würden, um alles perfekt in einem Versuch, optimieren diese in C (z.B. explizit EinstellungMADV_SEQUENTIAL
anstatt die kernel erraten, oder zwingt transparent huge pages)—aber du kannst eigentlichctypes
die Funktion auslibc
.readlines
auf eine 3GB-Datei sollte unter 4 GB, und falls Sie auch im pre-Prozess werden alle Zeilen in Listen von Werten im Speicher, das sollte nicht mehr als vielleicht 12 GB sind, so sind Sie immer noch in behaglichen Grenzen zu halten. Aber es bedeutet, Sie haben zu tun, alles zu Lesen-up-front, so dass die OS kann nicht helfen, pipeline-I/O-warten-und dein CPU arbeiten; Sie verschwenden Zeit auf malloc und cache-Fehler; etc. Wenn es einige Vorteile (z.B., lassen Sie es, verwenden Sie NumPy zu beschleunigen, einen langsamen Verarbeitung der Schleife), dann könnte man es, aber wenn nicht, warum tun Sie es?Ich weiß, diese Frage ist alt, aber ich wollte etwas ähnliches tun, habe ich einen einfachen Rahmen, der hilft, Sie zu Lesen und zu verarbeiten eine große Datei parallel. Das verlassen was ich auch versuchte, als Antwort.
Dies ist der code, ich gebe ein Beispiel am Ende
Sagen zum Beispiel, ich habe eine Datei, in die ich will, um die Anzahl der Wörter in jeder Zeile, dann wird die Verarbeitung jeder Zeile Aussehen würde
und rufen Sie dann die Funktion wie:
Verwenden, bekomme ich eine Geschwindigkeit von ~8 mal so im Vergleich zu vanilla Zeile für Zeile zu Lesen, die auf eine Beispiel-Datei der Größe ~20 GB, in dem ich einige mäßig komplizierte Verarbeitung in jeder Zeile.