Ich optimiere Code, dessen Hauptengpass darin besteht, auf eine sehr große Liste strukturähnlicher Objekte zuzugreifen. Derzeit verwende ich Namedtuples, um die Lesbarkeit zu verbessern. Ein schnelles Benchmarking mit 'timeit' zeigt jedoch, dass dies wirklich der falsche Weg ist, wenn Leistung ein Faktor ist:
Benanntes Tupel mit a, b, c:
>>> timeit("z = a.c", "from __main__ import a")
0.38655471766332994
Klasse __slots__
mit a, b, c:
>>> timeit("z = b.c", "from __main__ import b")
0.14527461047146062
Wörterbuch mit den Tasten a, b, c:
>>> timeit("z = c['c']", "from __main__ import c")
0.11588272541098377
Tupel mit drei Werten unter Verwendung eines konstanten Schlüssels:
>>> timeit("z = d[2]", "from __main__ import d")
0.11106188992948773
Liste mit drei Werten unter Verwendung eines konstanten Schlüssels:
>>> timeit("z = e[2]", "from __main__ import e")
0.086038238242508669
Tupel mit drei Werten unter Verwendung eines lokalen Schlüssels:
>>> timeit("z = d[key]", "from __main__ import d, key")
0.11187358437882722
Liste mit drei Werten unter Verwendung eines lokalen Schlüssels:
>>> timeit("z = e[key]", "from __main__ import e, key")
0.088604143037173344
Gibt es irgendetwas an diesen kleinen timeit
Tests, das sie ungültig machen würde? Ich lief jedes Mal mehrmals, um sicherzustellen, dass kein zufälliges Systemereignis sie ausgelöst hatte und die Ergebnisse fast identisch waren.
Es scheint, dass Wörterbücher die beste Balance zwischen Leistung und Lesbarkeit bieten, wobei die Klassen an zweiter Stelle stehen. Dies ist bedauerlich, da ich für meine Zwecke auch das Objekt sequenzartig haben muss; daher meine Wahl von namedtuple.
Listen sind wesentlich schneller, aber konstante Schlüssel sind nicht wartbar. Ich müsste eine Reihe von Indexkonstanten erstellen, dh KEY_1 = 1, KEY_2 = 2 usw., was ebenfalls nicht ideal ist.
Bleibe ich bei diesen Entscheidungen oder gibt es eine Alternative, die ich verpasst habe?