Gibt es in Python eine effiziente Methode zur Verkettung von Massenzeichenfolgen (wie StringBuilder in C # oder StringBuffer in Java)? Ich habe hier folgende Methoden gefunden :
- Einfache Verkettung mit
+
- Verwenden der Zeichenfolgenliste und
join
-methode - Verwendung
UserString
vomMutableString
Modul - Zeichenarray und das
array
Modul verwenden - Verwendung
cStringIO
vomStringIO
Modul
Aber was verwenden oder schlagen Experten vor und warum?
f''
Formatzeichenfolgen, die schneller sind als alle Alternativen in früheren Python-Versionen.Antworten:
Das könnte Sie interessieren: Eine Optimierungsanekdote von Guido. Obwohl es sich auch daran zu erinnern lohnt, dass dies ein alter Artikel ist und vor der Existenz von Dingen wie
''.join
(obwohl ich denke, dassstring.joinfields
es mehr oder weniger dasselbe ist)Aufgrund dessen ist das
array
Modul möglicherweise am schnellsten, wenn Sie Ihr Problem darin einschieben können. Ist''.join
aber wahrscheinlich schnell genug und hat den Vorteil, dass es idiomatisch ist und somit für andere Python-Programmierer leichter zu verstehen ist.Schließlich die goldene Regel der Optimierung: Optimieren Sie nicht, es sei denn, Sie wissen, dass Sie es müssen, und messen Sie, anstatt zu raten.
Mit dem
timeit
Modul können Sie verschiedene Methoden messen . Das kann Ihnen sagen , welches am schnellsten ist, anstatt dass zufällige Fremde im Internet Vermutungen anstellen.quelle
.join()
? Die Hauptfrage ist, ob a) eine Kopie der Zeichenfolge zur Verkettung erstellt wird (ähnlich wies = s + 'abc'
), für die O (n) Laufzeit erforderlich ist, oder b) einfach an die vorhandene Zeichenfolge angehängt wird, ohne eine Kopie zu erstellen, für die O (1) erforderlich ist. ?''.join(sequenceofstrings)
funktioniert normalerweise am besten - am einfachsten und am schnellsten.quelle
''.join(sequence)
Redewendung absolut . Es ist besonders nützlich, durch Kommas getrennte Listen zu erstellen:', '.join([1, 2, 3])
Gibt die Zeichenfolge an'1, 2, 3'
."".join(chr(x) for x in xrange(65,91))
--- In diesem Fall ist das zu verbindende Argument ein Iterator, der durch einen Generatorausdruck erstellt wird. Es gibt keine temporäre Liste, die erstellt wird.Python 3.6 hat das Spiel für die String-Verkettung bekannter Komponenten mit Literal String Interpolation geändert .
Angesichts des Testfalls aus der Antwort von mkoistinen mit Strings
Die Anwärter sind
f'http://{domain}/{lang}/{path}'
- 0,151 us'http://%s/%s/%s' % (domain, lang, path)
- 0,321 us'http://' + domain + '/' + lang + '/' + path
- 0,356 us''.join(('http://', domain, '/', lang, '/', path))
- 0,249 µs ( Beachten Sie , dass das Erstellen eines Tupels mit konstanter Länge etwas schneller ist als das Erstellen einer Liste mit konstanter Länge).Somit ist derzeit der kürzeste und schönste mögliche Code auch am schnellsten.
In Alpha-Versionen von Python 3.6 war die Implementierung von
f''
Zeichenfolgen so langsam wie möglich - tatsächlich entspricht der generierte Bytecode dem''.join()
Fall mit unnötigen Aufrufen, zustr.__format__
denen ohne Argumente nurself
unverändert zurückgegeben werden würde. Diese Ineffizienzen wurden vor 3.6 final behoben.Die Geschwindigkeit kann mit der schnellsten Methode für Python 2 verglichen werden, nämlich der
+
Verkettung auf meinem Computer. und das dauert 0,203 µs mit 8-Bit-Strings und 0,259 µs, wenn alle Strings Unicode sind.quelle
Es hängt davon ab, was Sie tun.
Nach Python 2.5 ist die Verkettung von Zeichenfolgen mit dem Operator + ziemlich schnell. Wenn Sie nur einige Werte verketten, funktioniert die Verwendung des Operators + am besten:
Wenn Sie jedoch eine Zeichenfolge in einer Schleife zusammenstellen, sollten Sie die Listenverbindungsmethode verwenden:
... aber beachten Sie, dass Sie eine relativ hohe Anzahl von Zeichenfolgen zusammenstellen müssen, bevor der Unterschied spürbar wird.
quelle
Optimieren Sie gemäß John Fouhys Antwort nicht, es sei denn, Sie müssen, aber wenn Sie hier sind und diese Frage stellen, kann dies genau daran liegen, dass Sie müssen . In meinem Fall musste ich einige URLs aus Zeichenfolgenvariablen zusammenstellen ... schnell. Mir ist aufgefallen, dass (bisher) niemand über die String-Format-Methode nachdenkt, also dachte ich, ich würde das versuchen, und hauptsächlich aus mildem Interesse dachte ich, ich würde den String-Interpolationsoperator für eine gute Messung hineinwerfen. Um ehrlich zu sein, hätte ich nicht gedacht, dass sich beides zu einer direkten '+' - Operation oder einer '' .join () zusammenfügen würde. Aber rate mal was? Auf meinem Python 2.7.5-System regiert der String-Interpolationsoperator sie alle und string.format () ist der schlechteste Performer:
Die Ergebnisse:
Wenn ich eine kürzere Domäne und einen kürzeren Pfad verwende, gewinnt die Interpolation immer noch. Der Unterschied ist jedoch bei längeren Saiten stärker ausgeprägt.
Nachdem ich nun ein schönes Testskript hatte, habe ich auch unter Python 2.6, 3.3 und 3.4 getestet. Hier sind die Ergebnisse. In Python 2.6 ist der Plus-Operator der schnellste! Bei Python 3 gewinnt Join. Hinweis: Diese Tests sind auf meinem System sehr wiederholbar. Daher ist 'plus' in 2.6 immer schneller, 'intp' in 2.7 immer schneller und 'join' in Python 3.x immer schneller.
Lektion gelernt:
tl; dr:
quelle
f'http://{domain}/{lang}/{path}'
.format()
hat drei Formen, um von schnell zu langsam:"{}".format(x)
,"{0}".format(x)
,"{x}".format(x=x)
Dies hängt ziemlich stark von der relativen Größe der neuen Zeichenfolge nach jeder neuen Verkettung ab. Mit dem
+
Operator wird für jede Verkettung eine neue Zeichenfolge erstellt. Wenn die Zwischenzeichenfolgen relativ lang sind,+
wird die zunehmend langsamer, da die neue Zwischenzeichenfolge gespeichert wird.Betrachten Sie diesen Fall:
Ergebnisse
1 0,00493192672729
2 0,000509023666382
3 0,00042200088501
4 0,000482797622681
Im Fall von 1 & 2 fügen wir eine große Zeichenfolge hinzu, und join () führt etwa zehnmal schneller aus. In den Fällen 3 und 4 fügen wir eine kleine Zeichenfolge hinzu, und '+' wird etwas schneller ausgeführt
quelle
Ich geriet in eine Situation, in der ich eine anhängbare Zeichenfolge unbekannter Größe benötigen würde. Dies sind die Benchmark-Ergebnisse (Python 2.7.3):
Dies scheint zu zeigen, dass '+ =' am schnellsten ist. Die Ergebnisse des Skymind-Links sind etwas veraltet.
(Mir ist klar, dass das zweite Beispiel nicht vollständig ist und die endgültige Liste zusammengefügt werden muss. Dies zeigt jedoch, dass das einfache Erstellen der Liste länger dauert als die Zeichenfolge concat.)
quelle
Ein Jahr später testen wir die Antwort von mkoistinen mit Python 3.4.3:
Nichts hat sich geändert. Join ist immer noch die schnellste Methode. Da intp in Bezug auf die Lesbarkeit wohl die beste Wahl ist, möchten Sie möglicherweise dennoch intp verwenden.
quelle
Inspiriert von den Benchmarks von @ JasonBaker, ist hier eine einfache, die 10
"abcdefghijklmnopqrstuvxyz"
Zeichenfolgen vergleicht und zeigt, dass dies.join()
schneller ist. selbst mit dieser winzigen Zunahme von Variablen:Verkettung
Beitreten
quelle
Für einen kleinen Satz von kurzen Strings (dh 2 oder 3 Saiten von nicht mehr als ein paar Zeichen), und ist immer noch viel schneller. Verwenden von mkoistinens wundervollem Skript in Python 2 und 3:
Wenn Ihr Code also eine große Anzahl separater kleiner Verkettungen ausführt, ist Plus der bevorzugte Weg, wenn die Geschwindigkeit entscheidend ist.
quelle
Wahrscheinlich ist "Neue F-Strings in Python 3.6" die effizienteste Art, Strings zu verketten.
Mit% s
Verwenden von .format
Mit f
Quelle: https://realpython.com/python-f-strings/
quelle