Beim Lesen der Dokumentation zu Python re
habe ich mich entschieden, einen Blick auf re.py
Quellcode zu werfen.
Als ich es öffnete, fand ich folgendes:
%Vor% Warum wird der Cache mit _cache.clear()
gelöscht, wenn er _MAXCACHE
der Einträge erreicht?
Ist es üblich, den Cache vollständig zu löschen und von vorne anzufangen?
Warum gerade nicht am längsten benutzt, wird der eingelöste Wert gelöscht?
Wenn ich raten müsste, würde ich sagen, dass es so gemacht wurde, um nicht zu verfolgen, wann / wie lange einzelne Werte im Cache gespeichert wurden, was sowohl Speicher- als auch Verarbeitungsaufwand verursachen würde. Da das verwendete Caching-Objekt ein Dictionary ist, das inhärent ungeordnet ist, gibt es keine gute Möglichkeit zu wissen, welche Order Items ohne ein anderes Caching-Objekt hinzugefügt wurden. Dies könnte behoben werden, indem ein OrderedDict anstelle eines Standardwörterbuchs verwendet wird, vorausgesetzt, Sie arbeiten mit Python & gt; = 2.7, aber ansonsten müssten Sie die Art und Weise, wie das Caching implementiert wurde, grundlegend neu gestalten a clear()
.
Hier ist ein Zitat von einem der Entwickler eines neuen regex
-Moduls, das für 3.3 im Hinblick auf das Caching geplant ist. Dies ist Teil einer Liste von Features, die das neue Modul vom aktuellen re
-Modul trennt.
7) Ändern Sie den neu kompilierten Ausdruckcache, um den Verdrängungszustand. Derzeit, wenn reguläre Ausdrücke kompiliert werden, Das Ergebnis wird zwischengespeichert, sodass, wenn derselbe Ausdruck erneut kompiliert wird, Es wird aus dem Cache abgerufen und es muss keine zusätzliche Arbeit geleistet werden. Dies Cache unterstützt bis zu 100 Einträge. Sobald der 100. Eintrag erreicht ist, wird der Cache wird gelöscht und eine neue Kompilierung muss stattfinden. Die Gefahr, alles sei gut selten, ist, dass man den 100. Ausdruck kompilieren kann, nur um diesen zu finden kompiliert es neu und muss, wenn es möglich ist, die gleiche Arbeit wiederholen wurden 3 Ausdrücke vor getan. Indem Sie diese Logik leicht modifizieren Es ist möglich, einen beliebigen Zähler zu erstellen, der einen Zeitstempel gibt jeder kompilierte Eintrag und anstatt den gesamten Cache zu löschen, wenn es erreicht Kapazität, nur die älteste Hälfte des Caches beseitigen, halten die Hälfte, die jünger ist. Dies sollte die Möglichkeit von sich auf Fälle einlassen, in denen eine sehr große Anzahl von regulären Ausdrücken vorhanden ist ständig neu kompiliert. Zusätzlich werde ich das Limit auf aktualisieren 256 Einträge, was bedeutet, dass die 128 neuesten beibehalten werden.
Dies deutet darauf hin, dass es eher die Faulheit des Entwicklers oder "eine Betonung der Lesbarkeit" ist, die das aktuelle Caching-Verhalten erklärt.
Der Caching-Punkt dient dazu, die durchschnittliche Anrufzeit der Funktion zu verringern. Der Overhead, der damit verbunden ist, mehr Informationen in _cache
zu behalten und ihn zu beschneiden, anstatt ihn zu löschen, würde die durchschnittliche Anrufzeit erhöhen. Der _cache.clear()
-Aufruf wird schnell abgeschlossen, und obwohl Sie Ihren Cache verlieren, ist dies vorzuziehen, einen Cache-Status beizubehalten und den Aufwand zu haben, einzelne Elemente aus dem Cache zu entfernen, wenn das Limit erreicht ist.
Es gibt einige Dinge, über die Sie bei der Berechnung der Cache-Effizienz nachdenken sollten:
Die Frage ist, dass # 3 Sinn macht, wenn es auch bedeutet, # 2 und # 4 zu erhöhen. Meine Vermutung ist, dass es nicht, oder der Unterschied ist vernachlässigbar genug, dass die Einhaltung des Codes vorzuziehen ist.