Einzelnen Beitrag anzeigen

idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#37

AW: Code-Kata: Cache-Klasse. Wer produziert den besten Code

  Alt 1. Aug 2015, 10:22
Das Interface der Klasse habe ich bewusst etwas anders gestaltet als in der Vorgabe
Wieso hältst Du dich nicht an die Vorgabe? Wieso soll sich ein Cache um das Schreiben kümmern? Wieso soll er Statistiken pflegen?
Wenn die Cache-Klasse auch das Schreiben besorgt, muss die Anwendung zu speichernde Daten nur an einer Stelle "abgeben", sonst muss sie die Daten sowohl in den Cache schreiben als auch selbst auf das externe Medium speichern.
Mir erscheint eine Klasse, die transparent den Zugriff auf die Daten organisiert und dabei die Daten cached, wesentlich zweckmässiger als eine reine Cache-Klasse, in der man erst nachschauen muss, ob die Daten dort sind, und sich andernfalls die Daten von draussen zu besorgen. Und wenn man das macht, dann muss die Cache-Klasse die Statistik über Hits und Misses natürlich selbst führen, das Programm draussen bekommt davon nichts mit (und braucht davon auch nichts mitzubekommen)

Natürlich wird man sich für eine reine Cache-Klasse in einer Anwendung einen Wrapper Schreiben, der das erledigt, aber so erscheint es mir wesentlich eleganter. Das Schreiben könnte in dieser Klasse auch leicht in einen separaten Thread ausgelagert und gequeued werden, wobei Elemente im Cache geschützt bleiben und nicht hinausgeworfen werden dürfen, bis sie wirklich auf das externe Medium geschrieben sind. Wenn du das Schreiben ausserhalb des Caches erledigst, wird es mit einem separaten Thread wesentlich komplizierter, denn es könnte dir passieren, dass ein Element aus dem Cache gelöscht wird und dann wieder angefordert wird, während das Schreiben auf das externe Medium noch in der Warteschlange des anderen Threads steckt.


Im Ernst: Sollen wir für deine Sonderklasse extra eigene Test- und Prüfroutinen schreiben?


Schreib Deine doch bitte um, dann kann man die mit den MRU-Ansätzen vergleichen. Dein Algorithmus ist wirklich sehr interessant.
Das ist allerdings hier ein schlagendes Argument, an das ich nicht gedacht habe.
Ich werde schauen wann ich dazukomme, auch wenn ich den Ansatz prinzipiell für schlechter halte.

Ein Tipp bezüglich der function TCache.FindPlaceInCache: integer; : Du rennst mit einer For-Schleife durch die Liste? Das ist jetzt aber nicht so sonderlich performant, denn ein Cache verwaltet i.a. Millionen von Elementen.
Diese Routine wird bei jedem Cache-Aufruf einmal komplett durch alle Elemente laufen. Das kannst Du mit einer Priority-Queue (bzw. einem Baum) viel effizienter Lösen. Der wird bei jedem Zugriff sortiert bzw. mit wenigen Handgriffen angepasst, sodass dein 'worst element' immer automatisch 'oben' ist. Aber die Implementierung ist natürlich ungemein komplexer.
Schon klar. Ich habe ja geschrieben:
Zitat:
Für die aktuellen Cacheelemente sollte wohl zusätzlich noch eine nach dem "Hinauswurfkriterium" sortierte Liste verwaltet werden (oder sogar statt des TDictionary, aber dadurch würde das Auffinden der im Cache vorhandenen Elemente wieder langsamer), damit man nicht alle Elemente durchgehen muss, wenn ein Element aus dem Cache zu entfernen ist, um herauszufinden, welches weggehört. Eine einfache verkettete Liste, wie sie namenloser in seinem Algorithmus verwendet, bringt nicht viel, weil man dann die verkettete Liste trotzdem immer durchgehen muss, um das an Stelle des hinausgeworfenen Elements hinzukommende neue Element an der richtigen Stelle einzufügen, das ist nämlich auch nicht unbedingt am Ende der Liste.
Gestern Nacht war es mir schon zu spät, da hatte ich keine Lust mehr, das auch noch zu machen. So schlimm, wie du schreibst, ist es nicht, weil die Routine nicht bei jedem Cachezugriff aufgerufen wird, sondern nur bei Cache Misses, wenn der Cache voll ist. Und Millionen von Elementen sind es wohl auch nicht, es werden ja nur die aktuell im Cache befindlichen Elemente durchgegangen. Andererseits stimmt das, was ich geschrieben habe, auch nicht ganz, eine einfache verkette Liste würde trotzdem eine deutliche Verbesserung bringen, weil neue Elemente zwar nicht immer ganz ans Ende kommen, aber tendenziell doch eher im hinteren (hintersten) Teil der Liste landen werden, vor allem, wenn die MRU-Gewichtung grösser ist als die Häufigkeits-Gewichtung, was sie wahrscheinlich in den meisten Anwendungsfällen sein sollte.

Jetzt muss ich weg, vielleich komme ich übers WE noch dazu, da weiter zu machen.

Geändert von idefix2 ( 1. Aug 2015 um 10:45 Uhr)
  Mit Zitat antworten Zitat