Ich spiele mit Listenverständnissen herum und bin auf einer anderen Seite auf diesen kleinen Ausschnitt gestoßen:
return ''.join([`num` for num in xrange(loop_count)])
Ich habe ein paar Minuten damit verbracht, die Funktion zu replizieren (durch Eingabe), bevor ich merkte, dass das `num`
Bit sie kaputt machte.
Was bewirkt das Einfügen einer Anweisung in diese Zeichen? Soweit ich sehen kann, entspricht es str (num). Aber als ich es zeitlich festlegte:
return ''.join([str(num) for num in xrange(10000000)])
Es dauert 4,09 Sekunden, während:
return ''.join([`num` for num in xrange(10000000)])
dauert 2,43s.
Beide liefern identische Ergebnisse, aber eines ist viel langsamer. Was geht hier vor sich?
EDIT: Seltsamerweise ... repr()
liefert etwas langsamere Ergebnisse als `num`
. 2,99s vs 2,43s. Verwenden von Python 2.6 (habe 3.0 noch nicht ausprobiert).
python
list-comprehension
Dominic Bou-Samra
quelle
quelle
Antworten:
Backticks sind ein veralteter Alias für
repr()
. Verwenden Sie sie nicht mehr, die Syntax wurde in Python 3.0 entfernt.Die Verwendung von Backticks scheint schneller zu sein als die Verwendung von
repr(num)
odernum.__repr__()
in Version 2.x. Ich denke, das liegt daran, dass eine zusätzliche Wörterbuchsuche im globalen Namespace (fürrepr
) bzw. im Namespace des Objekts (für__repr__
) erforderlich ist .Die Verwendung des
dis
Moduls beweist meine Annahme:Demontage zeigt:
f1
beinhaltet eine globale Suche nachrepr
,f2
eine Attributsuche nach__repr__
, während der Backtick-Operator in einem separaten Opcode implementiert ist. Da weder für die Wörterbuchsuche (LOAD_GLOBAL
/LOAD_ATTR
) noch für Funktionsaufrufe (CALL_FUNCTION
) ein Overhead anfällt, sind Backticks schneller.Ich denke, dass die Python-Leute entschieden haben, dass es
repr()
sich nicht lohnt , eine separate Low-Level-Operation zu haben, und dass beidesrepr()
und Backticks gegen das Prinzip verstoßenDaher wurde die Funktion in Python 3.0 entfernt.
quelle
Backtick-Zitate sind im Allgemeinen nicht nützlich und in Python 3 nicht mehr verfügbar.
Für das, was es wert ist, dies:
ist für mich etwas schneller als die Backtick-Version. Aber sich darüber Sorgen zu machen, ist wahrscheinlich eine vorzeitige Optimierung.
quelle
timeit
ergeben sich schnellere Ergebnisse''.join(map(repr, xrange(0, 1000000)))
als für''.join([repr(i) for i in xrange(0, 1000000)])
(noch schlimmer für''.join( (repr(i) for i in xrange(0, 1000000)) )
). Es ist ein bisschen enttäuschend ;-)map
wird in C mithilfe einer C-Schleife implementiert, die viel schneller ist als eine in der virtuellen Maschine ausgeführte Python-Schleife.map
scheint mir vollkommen klar und prägnant zu sein, und ich kenne Python nicht einmal.Ich vermute, dass
num
die Methode nicht definiert ist__str__()
, alsostr()
muss eine zweite Suche durchgeführt werden__repr__
.Die Backticks suchen direkt nach
__repr__
. Wenn dies zutrifft,repr()
sollten Sie anstelle der Backticks dieselben Ergebnisse erzielen.quelle