Ich habe eine teure Funktion wie folgt aus:Was ist die idiomatische Methode, Caching für eine Funktion zu implementieren, die keine struct-Methode ist?
pub fn get_expensive_value(n: u64): u64 {
let ret = 0;
for 0 .. n {
// expensive stuff
}
ret
}
Und es sehr häufig mit dem gleichen Argument aufgerufen wird. Es ist rein, das heißt, es wird das gleiche Ergebnis zurückgeben und kann einen Cache verwenden.
Wenn dies eine Struct-Methode wäre, würde ich ein Mitglied der Struktur hinzufügen, die als Cache fungiert, aber es ist nicht. Also meine Option, um eine statische Aufladung zu sein scheint, zu verwenden:
static mut LAST_VAL: Option<(u64, u64)> = None;
pub fn cached_expensive(n: u64) -> u64 {
unsafe {
LAST_VAL = LAST_VAL.and_then(|(k, v)| {
if k == n {
Some((n,v))
} else {
None
}
}).or_else(|| {
Some((n, get_expensive_value(n)))
});
let (_, v) = LAST_VAL.unwrap();
v
}
}
Nun, ich habe unsafe
zu verwenden. Anstelle der static mut
könnte ich eine RefCell
in eine const
setzen. Aber ich bin nicht davon überzeugt, dass es sicherer ist - es vermeidet einfach, den Block unsafe
zu benutzen. Ich dachte an eine Mutex
, aber ich denke nicht, dass mich das auch Threadsicherheit bringen wird.
Die Neugestaltung des Codes zur Verwendung einer Struktur für die Speicherung ist nicht wirklich eine Option.
Duplizieren von [Wie erstelle ich eine globale, wandelbar Singletons?] (http://stackoverflow.com/questions/27791532/how- do-i-create-a-global-veränderbares Singleton). – Shepmaster
Oder Sie können die Signatur von "cached_expensive" ändern, um den Cache als weiteren Parameter zu akzeptieren. – Shepmaster
Ich glaube nicht, dass dies ein Duplikat ist. Meine Frage bezieht sich speziell auf das Caching und, während mein Ausgangspunkt ein globaler, veränderbarer Singleton ist, ist das nebensächlich und eine gute Lösung könnte erklären, wie (zum Beispiel) eine 'RefCell' oder' Mutex' dies besser machen oder komplett anbieten könnte verschiedene alternative strukturell. –