Memo-Bibliotheken für C?

Lesezeit: 6 Minuten

Für ein Projekt, an dem ich arbeite, gibt es eine Reihe von Zuständen, in denen Berechnungen zuverlässig dieselben Ergebnisse liefern (und keine Nebenwirkungen haben). Die offensichtliche Lösung wäre, die Memoisierung für alle kostspieligen Funktionen zu verwenden.

Ich müsste eine Memoisierung haben, die mehr als einen Zustand handhabt (damit ich einen Cache-Satz ungültig machen könnte, ohne einen anderen ungültig zu machen). Kennt jemand eine gute C-Bibliothek für so etwas? (Beachten Sie, dass es nicht C++ sein kann, wir sprechen von C.)

Ich habe mit einigen guten Implementierungen in Python gearbeitet, die Decorators verwenden, um sich eine Reihe verschiedener Funktionen flexibel merken zu können. Ich frage mich, ob es eine generische Bibliothek gibt, die ähnliche Dinge mit C tun könnte (obwohl wahrscheinlich eher mit explizitem Funktionsumbruch als mit bequemer Syntax). Ich denke nur, dass es albern wäre, jeder Funktion einzeln Caching hinzufügen zu müssen, wenn es sich um ein häufig genug auftretendes Problem handelt, für das es einige Standardlösungen geben muss.

Folgende Eigenschaften würde ich suchen:

  1. Kann Funktionen mit verschiedenen Eingabe- und Ausgabetypen zwischenspeichern
  2. Verwaltet mehrere verschiedene Caches (so dass Sie kurz- und langfristiges Caching haben können)
  3. Hat gute Funktionen zum Invalidieren von Caches
  4. Soll von Wrapping-Funktionen verwendet werden, anstatt vorhandene Funktionen zu ändern

Kennt jemand eine C-Implementierung, die alle oder die meisten dieser Anforderungen erfüllen kann?

  • Wie so etwas funktionieren soll, ist mir nicht klar. Ein Merkblatt wie memoize(void*func, void*returnVal, int return size, ...)? Scheint kompliziert und zerbrechlich. Ein Haufen Präprozessor-Hacks? Du kann machen Sie erstaunliche Dinge mit dieser Art von Zeug, aber es neigt auch dazu, zerbrechlich zu sein und kann zu einem Albtraum für die Wartung werden. Aber auf jeden Fall gute Frage.

    – dmckee — Ex-Moderator-Kätzchen

    20. Mai 2011 um 1:55 Uhr


  • Es wäre viel schöner in C++11 mit perfekter Weiterleitung, aber ich könnte mir vorstellen, dass es in C mit etwas Leistungsverlust gemacht wird, indem ich ein Wörterbuch mit Typdeskriptoren zur Verfügung stelle memoize(). Ungefähr so ​​zerbrechlich wie printf().

    – Simon Buchan

    20. Mai 2011 um 2:20 Uhr

  • @Namey: Die Leute schreiben ständig Memos in C, aber eine generische C-Bibliothek – „generisch“ in Bezug darauf, wie C++ Vorlagen hat oder wie Python-Dekorateure dies verpacken – ist schmerzhaft und voller Fallstricke.

    – Fred Nurk

    22. Mai 2011 um 4:15 Uhr

  • @Fred: Das sehe ich wohl anders. Ist es weniger schmerzhaft und voller Fallstricke, das Rad jedes Mal neu erfinden zu müssen, wenn man sich eine einzelne Funktion merken möchte? Ich habe lieber eine schmerzhafte Sache an einem Ort zu pflegen, als 1000 Ad-hoc-Implementierungen, die überall im Code verstreut sind.

    – Nämlich

    22. Mai 2011 um 7:19 Uhr


  • @Namey: Ich meinte “schmerzhaft und voller Fallstricke”. jeder Einsatz dieser Bibliothek. Soweit beim Schreiben, Hinzufügen von “internen” Memos (unter Verwendung von Kenntnissen der Implementierung). sehr einfach im Vergleich zum Schreiben einer generischen Bibliothek. Die Kosten für die Wiederholung sind meiner Meinung nach geringer als die Kosten für Alternativen.

    – Fred Nurk

    22. Mai 2011 um 8:02 Uhr

Benutzer-Avatar
Name

Okay, da es keine Memoization-Bibliotheken für C gab und ich nach einer Drop-In-Lösung suchte, um vorhandene C-Funktionen in einer Codebasis zu memoisieren, habe ich meine eigene kleine Memoization-Bibliothek erstellt, die ich unter der APL 2.0 veröffentliche. Hoffentlich finden die Leute das nützlich und es wird nicht auf anderen Compilern abstürzen und brennen. Wenn es Probleme gibt, senden Sie mir hier eine Nachricht und ich werde mich darum kümmern, wann immer ich Zeit habe (was wahrscheinlich in Schritten von Monaten gemessen wird).

Diese Bibliothek ist nicht auf Geschwindigkeit ausgelegt, aber sie funktioniert und wurde getestet, um sicherzustellen, dass sie relativ einfach zu verwenden ist und bei meinen Tests keine Speicherlecks aufweist. Im Grunde lässt mich dies memoization zu Funktionen hinzufügen, die dem Decorator-Muster ähneln, an das ich in Python gewöhnt bin.

Die Bibliothek befindet sich derzeit auf SourceForge als C-Memo-Bibliothek. Es wird mit einem kleinen Benutzerhandbuch und einigen freizügig lizenzierten Bibliotheken von Drittanbietern für generisches Hashing geliefert. Wenn sich der Standort ändert, werde ich versuchen, diesen Link zu aktualisieren. Ich fand das hilfreich bei der Arbeit an meinem Projekt, hoffentlich finden andere es für ihre Projekte nützlich.

  • Ich habe Ihre Bibliothek verwendet und es funktioniert! Ziemlich gut. Ich habe ziemlich genau das gleiche Programm in Python geschrieben, es lief in 2m 50s native, während 7s in Pypy. Das C-Programm lief in 46s.

    – der Doktar

    25. Mai 2013 um 17:59 Uhr

  • Froh das zu hören. Ich habe ein paar Aufräumarbeiten vorgenommen, damit es mit mehr Compilern problemlos funktioniert. Außerdem ist das eine beeindruckende Zeit für PyPy. Sie müssen einige interessante Dinge zur Optimierung unter der Haube tun.

    – Nämlich

    14. Februar 2014 um 19:16 Uhr

  • Ja, nun, PyPy wird seit vielen Jahren von einem Team von Doktoranden entwickelt … also schätze ich, dass sie ziemlich harte Mathematik verwenden. Das Programm, das ich geschrieben habe, wurde geschrieben, um irgendein Project-Euler-Problem zu lösen, obwohl es so lange her ist und ich vergessen habe, welches.

    – der Doktar

    18. Februar 2014 um 7:00 Uhr

  • Ja, ich weiss. Es ist jedoch immer noch ziemlich beeindruckend, eine 25-fache Beschleunigung gegenüber dem ursprünglichen Python zu erreichen. Ich hatte mich an die üblichen Beschleunigungen gegenüber cPython erinnert, die eher in der Größenordnung von 2-5x lagen.

    – Nämlich

    20. Februar 2014 um 23:19 Uhr

Benutzer-Avatar
Karl Lambert

Auswendiglernen ist so gut wie in die Haskell-Sprache eingebaut. Du kannst Rufen Sie diese Funktionalität von c auf

Aktualisieren:
Ich lerne immer noch etwas über funktionales Programmieren, aber ich weiß, dass das Memoisieren in der funktionalen Programmierung ziemlich verbreitet ist, weil die Sprachfunktionen es einfach machen. Ich lerne f#. Ich kenne Haskell nicht, aber es ist die einzige mir bekannte funktionale Sprache, die mit c interagiert. Möglicherweise finden Sie eine andere funktionale Programmiersprache, die sich besser mit c verbindet als die von Haskell.

  • Sicherlich ein interessanter Kommentar. Es scheint jedoch ein bisschen übertrieben zu sein, C in Haskell zu verpacken. Ich würde mir auch Sorgen über die potenzielle Leistungseinbuße durch zusätzlichen Haskell-generierten C-Code machen, der nicht wirklich benötigt wird. Es würde auch das Problem geben, dass mir unklar ist, wie dieser Ansatz helfen würde, Funktionen zu speichern, die in C implementiert sind.

    – Nämlich

    22. Mai 2011 um 7:15 Uhr

  • Ich habe meine Antwort etwas detaillierter aktualisiert. Es ist nicht sehr hilfreich, und ich hätte diese Antwort überhaupt nicht gegeben, wenn Ihre Frage nicht seit 2 Tagen ohne Antwort hier ist. Wenn es für Sie in einer Sackgasse endet, tut es mir leid und ich wünsche Ihnen viel Glück. Aber wenn es klappt, dann bin ich froh, geholfen zu haben.

    – Karl Lambert

    22. Mai 2011 um 16:24 Uhr

  • Hey, danke, dass du es wenigstens versucht hast. Eine unkonventionelle Antwort ist immer noch zumindest ein Versuch.

    – Nämlich

    22. Mai 2011 um 17:02 Uhr

Warum kann es nicht einfach C++ sein?

Schauen Sie sich nur als Ausgangspunkt diese Merkfunktion an:

Erklärung:

template<typename T, typename F>
auto Memoize(T key, F function) {
  static T memory_key = key;
  static auto memory = function(memory_key);
  if (memory_key != key) {
    memory_key = key;
    memory = function(memory_key);
  }

  return memory;
}

Anwendungsbeispiel:

auto index = Memoize(value, IndexByLetter);

1362730cookie-checkMemo-Bibliotheken für C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy