12 个版本 (6 个破坏性更新)
使用旧的 Rust 2015
0.6.1 | 2020 年 11 月 21 日 |
---|---|
0.6.0 | 2018 年 11 月 13 日 |
0.5.2 | 2015 年 9 月 25 日 |
0.4.0 | 2015 年 9 月 2 日 |
0.0.3 | 2015 年 5 月 27 日 |
#64 在 内存管理 中
33,576 每月下载量
用于 8 个 Crates (6 个直接使用)
26KB
464 行
lifeguard
对象池管理器
示例
Pool
保留在智能指针中拥有的值。
extern crate lifeguard;
use lifeguard::*;
fn main() {
let pool : Pool<String> = pool().with(StartingSize(10)).build();
{
let string = pool.new_from("Hello, World!"); // Remove a value from the pool
assert_eq!(9, pool.size());
} // Values that have gone out of scope are automatically moved back into the pool.
assert_eq!(10, pool.size());
}
从池中取出的值可以解引用以访问/修改其内容。
extern crate lifeguard;
use lifeguard::*;
fn main() {
let pool : Pool<String> = pool().with(StartingSize(10)).build();
let mut string = pool.new_from("cat");
string.push_str("s love eating mice"); //string.as_mut() also works
assert_eq!("cats love eating mice", *string);
}
值可以被解包,从池中分离。
extern crate lifeguard;
use lifeguard::*;
fn main() {
let pool : Pool<String> = pool().with(StartingSize(10)).build();
{
let string : String = pool.new().detach();
} // The String goes out of scope and is dropped; it is not returned to the pool
assert_eq!(9, pool.size());
}
值可以被手动放入/返回到池中。
extern crate lifeguard;
use lifeguard::*;
fn main() {
let pool : Pool<String> = pool().with(StartingSize(10)).build();
{
let string : String = pool.detached(); // An unwrapped String, detached from the Pool
assert_eq!(9, pool.size());
let rstring : Recycled<String> = pool.attach(string); // The String is attached to the pool again
assert_eq!(9, pool.size()); // but it is still checked out from the pool
} // rstring goes out of scope and is added back to the pool
assert_eq!(10, pool.size());
}
Pool
的构建器 API 可以用来自定义池的行为。
extern crate lifeguard;
use lifeguard::*;
fn main() {
let pool : Pool<String> = pool()
// The pool will allocate 128 values for immediate use. More will be allocated on demand.
.with(StartingSize(128))
// The pool will only grow up to 4096 values. Further values will be dropped.
.with(MaxSize(4096))
// The pool will use this closure (or other object implementing Supply<T>) to allocate
.with(Supplier(|| String::with_capacity(1024)))
.build();
// ...
}
非常不科学的基准测试
基准测试源代码可以在 这里 找到。测试在一台早期的 2015 年 MacBook Pro 上运行。
每个基准测试都有三种风味
tests::*_standard
:使用系统分配器创建新值。tests::*_pooled_rc
:使用Pool
创建新值,这些值持有Rc
对Pool
的引用。这些值可以自由传递到其他作用域。tests::*_pooled
:使用Pool
创建新值,这些值持有对Pool
的本地作用域引用。这些值创建成本最低,但绑定到Pool
的生命周期。
未初始化的分配
比较创建一个新的 String
(使用 String::with_capacity
,因为 String::new
不立即分配)与从池中检索 String
的成本。
tests::allocation_standard ... bench: 5,322,513 ns/iter (+/- 985,898)
tests::allocation_pooled_rc ... bench: 784,885 ns/iter (+/- 95,245)
tests::allocation_pooled ... bench: 565,864 ns/iter (+/- 66,036)
初始化分配
比较分配一个新String
并将其初始化为给定值(通过&str::to_owned
)的成本与从池中检索String
并将其初始化为相同值的成本。
tests::initialized_allocation_standard ... bench: 5,329,948 ns/iter (+/- 547,725)
tests::initialized_allocation_pooled_rc ... bench: 1,151,493 ns/iter (+/- 119,293)
tests::initialized_allocation_pooled ... bench: 927,214 ns/iter (+/- 147,935)
VecVecString>> 分配
创建一个初始化的字符串二维向量。所有创建的Vec
和String
都来自Pool
,如果适用。改编自此基准测试。
tests::vec_vec_str_standard ... bench: 1,353,906 ns/iter (+/- 142,094)
tests::vec_vec_str_pooled_rc ... bench: 298,087 ns/iter (+/- 168,703)
tests::vec_vec_str_pooled ... bench: 251,082 ns/iter (+/- 24,408)
欢迎提出想法和PR!
灵感来源于frankmcsherry的recycler。