Schnell string zu integer Konvertierung in Python

Ein einfaches problem, wirklich: Sie haben eine Milliarde (1e+9) unsigned 32-bit-Ganzzahlen gespeichert, die als dezimale ASCII-strings in eine TSV (tab-separated values) - Datei. Konvertierung mithilfe int() ist schrecklich langsam im Vergleich zu anderen Werkzeugen arbeiten auf dem gleichen Datenbestand. Warum? Und noch wichtiger: wie Sie es schneller zu machen?

Daher die Frage: was ist der Schnellste Weg möglich zu konvertieren eine Zeichenfolge in eine Ganzzahl in Python?

Was ich wirklich darüber nachdenken, einige semi-hidden Python-Funktionen, die sein könnte (ab)für diesen Zweck verwendet, nicht anders als Guido die Nutzung von array.array in seinem "Optimierung Anekdote".

Sample-Daten (mit tabs erweitert werden, um Leerzeichen)

38262904        "pfv"              2002-11-15T00:37:20+00:00
12311231        "tnealzref"        2008-01-21T20:46:51+00:00
26783384        "hayb"             2004-02-14T20:43:45+00:00
812874          "qevzasdfvnp"      2005-01-11T00:29:46+00:00
22312733        "bdumtddyasb"      2009-01-17T20:41:04+00:00

Die Zeit, die es dauert das Lesen der Daten ist hier irrelevant, die Verarbeitung der Daten ist der Engpass.

Microbenchmarks

Alle der folgenden sind interpretierte Sprachen. Die host-Maschine läuft auf 64-bit-Linux.

Python 2.6.2 mit IPython 0.9.1, ~214k Wandlungen pro Sekunde (100%):

In [1]: strings = map(str, range(int(1e7)))

In [2]: %timeit map(int, strings);
10 loops, best of 3: 4.68 s per loop

REBOL-Version 3.0 2.100.76.4.2, ~231kcps (108%):

>> strings: array n: to-integer 1e7 repeat i n [poke strings i mold (i - 1)]
== "9999999"

>> delta-time [map str strings [to integer! str]]
== 0:00:04.328675

REBOL 2.7.6.4.2 (15-Mar-2008), ~523kcps (261%):

Als John bemerkt in den Kommentaren, diese version hat nicht erstellen Sie eine Liste von Ganzzahlen umgewandelt, so dass die Geschwindigkeit-Verhältnis gegeben ist, die relativ zu Python 4.99 s Laufzeit for str in strings: int(str).

>> delta-time: func [c /local t] [t: now/time/precise do c now/time/precise - t]

>> strings: array n: to-integer 1e7 repeat i n [poke strings i mold (i - 1)]
== "9999999"

>> delta-time [foreach str strings [to integer! str]]
== 0:00:01.913193

KDB+ 2,6 t 2009.04.15, ~2016kcps (944%):

q)strings:string til "i"$1e7

q)\t "I"$strings
496
  • Versuchen numpy.fromfile laden 'eine Milliarde positiven ganzen zahlen" (btw, was meinst du mit 'Milliarden' (es ist 10**9 in UNS, es könnte sein 10**12 in Großbritannien)?
  • Guter Fang über die Milliarden, obwohl die letztere Verwendung kam aus der Mode in Großbritannien in den 1970er-Jahren.
  • Haben Sie versucht, den code zu kompilieren ?
  • (1) Bitte mehr explizit als "gespeichert als ASCII-Zeichenketten in einer text-Datei". Fixe Spalten oder getrennt? Ist das der einzige Typ der Daten in der Datei? Zeigen ein paar Beispiel-Zeilen. (2) Zeigen Sie uns den code, den SIE derzeit verwenden, wenn Sie uns glauben machen wollen, dass int() ist das problem und das ist keine Hausaufgaben-Frage (3) Bitte drücken Sie die Geschwindigkeit in SI-Einheiten eher als "schrecklich langsam". (4) Welche anderen tools? (5) Welche Plattform und welche version von Python?
  • (6) Was ist die Durchschnittliche Anzahl der Ziffern in einen integer? (7) Sind die Ziffern dezimal/hex/oktal/etwas anderes?
  • Vielen Dank für Ihre Kommentare, John. Ich integrierte Sie in die Frage.
  • Die Python microbenchmark-code erstellt eine Liste von int-Ergebnisse und wirft die Liste Weg. Tun die REBOL-und KDB-codes bauen auch einen Behälter mit den Ergebnissen?
  • KDB und die jüngsten REBOL 3-code tun, der REBOL-2-code nicht. Ich aktualisiert die Messungen, um dies zu reflektieren.

InformationsquelleAutor earl | 2009-08-20
Schreibe einen Kommentar