Gibt es in Python eine String-Klasse wie StringBuilder
in C #?
Gibt es in Python eine String-Klasse wie StringBuilder
in C #?
Antworten:
Es gibt keine Eins-zu-Eins-Korrelation. Einen wirklich guten Artikel finden Sie unter Effiziente String-Verkettung in Python :
Das Erstellen langer Zeichenfolgen in der Python-Programmiersprache kann manchmal zu sehr langsam laufendem Code führen. In diesem Artikel untersuche ich die Rechenleistung verschiedener String-Verkettungsmethoden.
Ich habe den Code von Oliver Crow (Link von Andrew Hare) verwendet und ihn ein wenig angepasst, um Python 2.7.3 anzupassen. (mit timeit package). Ich lief auf meinem PC, Lenovo T61, 6 GB RAM, Debian GNU / Linux 6.0.6 (Squeeze).
Hier ist das Ergebnis für 10.000 Iterationen:
Methode 1: 0,0538418292999 Sekunden Prozessgröße 4800 kb Methode 2: 0,22602891922 Sekunden Prozessgröße 4960 kb Methode 3: 0,0605459213257 Sekunden Prozessgröße 4980 kb Methode 4: 0,0544030666351 Sekunden Prozessgröße 5536 kb Methode 5: 0,0551080703735 Sekunden Prozessgröße 5272 kb Methode 6: 0,0542731285095 Sekunden Prozessgröße 5512 kb
und für 5.000.000 Iterationen (Methode 2 wurde ignoriert, weil sie wie für immer zu langsam lief):
Methode 1: 5,88603997231 Sekunden Prozessgröße 37976 kb Methode 3: 8,40748500824 Sekunden Prozessgröße 38024 kb Methode 4: 7,96380496025 Sekunden Prozessgröße 321968 kb method5: 8.03666186333 sec Prozessgröße 71720 kb Methode 6: 6,68192911148 Sekunden Prozessgröße 38240 kb
Es ist ziemlich offensichtlich, dass Python-Leute großartige Arbeit geleistet haben, um die Verkettung von Strings zu optimieren, und wie Hoare sagte: "Vorzeitige Optimierung ist die Wurzel allen Übels" :-)
Sich auf Compiler-Optimierungen zu verlassen, ist fragil. Den in der akzeptierten Antwort und den von Antoine-tran angegebenen Zahlen verknüpften Benchmarks ist nicht zu trauen. Andrew Hare macht den Fehler, einen Aufruf an repr
in seine Methoden aufzunehmen. Das verlangsamt alle Methoden gleichermaßen, verdeckt aber die wirkliche Strafe beim Erstellen des Strings.
Verwenden Sie join
. Es ist sehr schnell und robuster.
$ ipython3
Python 3.5.1 (default, Mar 2 2016, 03:38:02)
IPython 4.1.2 -- An enhanced Interactive Python.
In [1]: values = [str(num) for num in range(int(1e3))]
In [2]: %%timeit
...: ''.join(values)
...:
100000 loops, best of 3: 7.37 µs per loop
In [3]: %%timeit
...: result = ''
...: for value in values:
...: result += value
...:
10000 loops, best of 3: 82.8 µs per loop
In [4]: import io
In [5]: %%timeit
...: writer = io.StringIO()
...: for value in values:
...: writer.write(value)
...: writer.getvalue()
...:
10000 loops, best of 3: 81.8 µs per loop
repr
Aufruf dominiert die Laufzeit, aber es besteht keine Notwendigkeit, den Fehler persönlich zu machen.
Python hat mehrere Dinge, die ähnliche Zwecke erfüllen:
list(your_string)
. Sie können auch eine UserString.MutableString
dafür verwenden.(c)StringIO.StringIO
ist nützlich für Dinge, die sonst eine Datei benötigen würden, aber weniger für die allgemeine Zeichenfolgenerstellung.Mit Methode 5 von oben (The Pseudo File) können wir eine sehr gute Leistung und Flexibilität erzielen
from cStringIO import StringIO
class StringBuilder:
_file_str = None
def __init__(self):
self._file_str = StringIO()
def Append(self, str):
self._file_str.write(str)
def __str__(self):
return self._file_str.getvalue()
jetzt benutze es
sb = StringBuilder()
sb.Append("Hello\n")
sb.Append("World")
print sb
Sie können StringIO oder cStringIO ausprobieren
Es gibt kein explizites Analogon - ich denke, es wird erwartet, dass Sie Zeichenfolgenverkettungen (wahrscheinlich wie oben beschrieben optimiert) oder Klassen von Drittanbietern (ich bezweifle, dass sie viel effizienter sind) verwenden - Listen in Python sind dynamisch typisiert, sodass sie nicht schnell funktionieren char [] für Puffer, wie ich annehme). Stringbuilder-ähnliche Klassen sind keine vorzeitige Optimierung, da Strings in vielen Sprachen angeboren sind (Unveränderlichkeit) - dies ermöglicht viele Optimierungen (z. B. Verweisen auf denselben Puffer für Slices / Teilzeichenfolgen). Stringbuilder- / Stringbuffer- / Stringstream-ähnliche Klassen arbeiten viel schneller als das Verketten von Strings (wodurch viele kleine temporäre Objekte erzeugt werden, für die noch Zuordnungen und Speicherbereinigung erforderlich sind) und sogar das Formatieren von printf-ähnlichen Tools für das Formatieren von Zeichenfolgen, ohne dass der Aufwand für das Formatieren von Formatierungsmustern ziemlich aufwendig ist viele Formataufrufe.
Wenn Sie hier nach einer schnellen String-Verkettungsmethode in Python suchen, benötigen Sie keine spezielle StringBuilder-Klasse. Einfache Verkettung funktioniert genauso gut ohne den Leistungsverlust in C #.
resultString = ""
resultString += "Append 1"
resultString += "Append 2"
Siehe Antoine-trans Antwort für Leistungsergebnisse