5 个版本 (3 个稳定)
1.2.0 | 2019年8月15日 |
---|---|
1.1.1 | 2019年2月14日 |
0.2.0 | 2019年2月5日 |
0.1.0 | 2019年1月27日 |
#231 在 缓存
每月1,115 次下载
16KB
274 行
FnMemo
一个用于创建函数记忆化的 Rust 库。
文档:API 参考
使用方法
将以下依赖项添加到您的 Cargo.toml
[dependencies]
fn-memo = "1.2"
默认情况下,fn-memo
包含同步 API,这引入了相关依赖。如果您只在单个线程中使用记忆化并想减少依赖项,请使用以下配置。
[dependencies]
fn-memo = { version = "1.2", default-features = false }
lib.rs
:
一个使用缓存来提高性能的函数记忆化库。
您可以使用 unsync::memoize
函数创建记忆化。它使用 HashMap
进行缓存。
use fn_memo::{FnMemo, unsync, recur_fn::direct};
let mul_2 = unsync::memoize(direct(|n| {
println!("Evaluating {}", n);
n * 2
}));
assert_eq!(0, mul_2.call(0)); // Output "Evaluating 0."
assert_eq!(4, mul_2.call(2)); // Output "Evaluating 2."
assert_eq!(10, mul_2.call(5)); // Output "Evaluating 5."
assert_eq!(4, mul_2.call(2)); // No output. The result is cached.
mul_2.clear_cache();
assert_eq!(4, mul_2.call(2)); // Output "Evaluating 2."
memoize
函数接受一个 RecurFn
参数,这允许您记忆化递归函数,每次递归的结果将被缓存。有关详细信息,请参阅 recur-fn
的 API 参考。
use fn_memo::{FnMemo, unsync, recur_fn::recur_fn};
let fib = unsync::memoize(recur_fn(|fib, n: usize| {
println!("Evaluating {}", n);
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
}));
assert_eq!(55, fib.call(10));
assert_eq!(5, fib.call(5));
上面的代码将输出从 0 到 10 的评估。每个都是只输出一次。
对于序列(即接受 usize
参数的函数),您也可以使用 unsync::memoize_seq
。它使用 Vec
作为桶来缓存。它具有更好的性能,并且所需的内存与已缓存的最大的参数成正比。
您可以通过实现 unsync::Cache
trait 来自定义缓存的数据结构,并使用 unsync::Memo::new
方法创建记忆化。
unsync
命名空间下的 API 用于单线程。即使缓存的函数不是,unsync::memoize
的结果也不 Sync
。
use std::{sync::Arc, thread};
use fn_memo::{FnMemo, unsync, recur_fn::direct};
let f = Arc::new(unsync::memoize(direct(|n: i32| n)));
thread::spawn(move || { f }); // Compile Error
同步记忆化 API 在 sync
命名空间下。
use fn_memo::{FnMemo, sync::chashmap, recur_fn::direct};
use std::thread;
use std::sync::Arc;
let mul_2 = Arc::new(chashmap::memoize(direct(|n| {
println!("Evaluating {}", n);
n * 2
})));
let mut threads = Vec::new();
for _ in 0..4 {
threads.push(thread::spawn({
let mul_2 = Arc::clone(&mul_2);
move || {
for n in 0..10 {
assert_eq!(n*2, mul_2.call(n));
}
}
}));
}
for thread in threads {
thread.join().unwrap();
}
上面的代码将输出从 0 到 9 的评估。每个都是只输出一次。
依赖项
~11–440KB