#stack #box #alloc #dst #no-std

no-std smallbox

Small Box 优化:将小对象存储在栈上,大对象则回退到堆上

11 个版本

0.8.2 2023年9月26日
0.8.1 2021年12月6日
0.8.0 2019年11月3日
0.7.5 2019年7月23日
0.4.1 2017年6月2日

#89数据结构

Download history 2569/week @ 2024-04-08 2759/week @ 2024-04-15 2671/week @ 2024-04-22 3003/week @ 2024-04-29 2645/week @ 2024-05-06 2118/week @ 2024-05-13 2690/week @ 2024-05-20 2600/week @ 2024-05-27 3247/week @ 2024-06-03 3651/week @ 2024-06-10 2460/week @ 2024-06-17 2447/week @ 2024-06-24 1961/week @ 2024-07-01 3098/week @ 2024-07-08 2959/week @ 2024-07-15 2445/week @ 2024-07-22

10,688 每月下载量
用于 53 个crate(直接使用2个)

MIT 许可证

30KB
453

smallbox

Build Status crates.io

Small Box 优化:将小对象存储在栈上,大对象则回退到堆上。需要 Rust 1.56+。

文档

用法

首先,将以下内容添加到您的 Cargo.toml

[dependencies]
smallbox = "0.8"

接下来,将其添加到您的crate根目录

extern crate smallbox;

如果您想使此crate与动态大小类型一起工作,您可以通过以下方式请求

[dependencies]
smallbox = { version = "0.8", features = ["coerce"] }

当前 smallbox 默认链接到标准库,但如果您想在 #![no_std] 环境或crate中使用此crate,您可以通过以下方式请求

[dependencies.smallbox]
version = "0.8"
features = ["coerce"]
default-features = false

功能标志

此crate有以下 cargo 功能标志

  • std

    • 可选,默认启用
    • 使用 libstd
    • 如果选择不使用 std 功能标志,则将链接到 alloc crate,这需要 nightly rust。
  • coerce

    • 可选
    • 需要 nightly rust
    • 允许从有大小 SmallBox 自动转换到无大小 SmallBox

无大小类型

有两种方法可以获得无大小 SmallBox:使用 smallbox!() 宏或将大小 SmallBox 实例转换(需要 nightly 编译器)。

使用 smallbox!() 宏是稳定rust的唯一选项。此宏将检查给定值和目标类型 T 的类型。对于任何无效的类型转换,此宏将在编译时引发错误。

一旦启用特性 coerce,在必要时,尺寸为 SmallBox<T> 的对象将自动转换为 SmallBox<T: ?Sized>

示例

通过 SmallBox 消除小对象的堆分配

use smallbox::SmallBox;
use smallbox::space::S4;

let small: SmallBox<_, S4> = SmallBox::new([0; 2]);
let large: SmallBox<_, S4> = SmallBox::new([0; 32]);

assert_eq!(small.len(), 2);
assert_eq!(large.len(), 32);

assert_eq!(*small, [0; 2]);
assert_eq!(*large, [0; 32]);

assert!(small.is_heap() == false);
assert!(large.is_heap() == true);

未指定大小的类型

使用宏 smallbox!() 构建

#[macro_use]
extern crate smallbox;

use smallbox::SmallBox;
use smallbox::space::*;

let array: SmallBox<[usize], S2> = smallbox!([0usize, 1]);

assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);

启用 coerce 特性

use smallbox::SmallBox;
use smallbox::space::*;
 
let array: SmallBox<[usize], S2> = SmallBox::new([0usize, 1]);

assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);

Any 降级

#[macro_use]
extern crate smallbox;

use std::any::Any;
use smallbox::SmallBox;
use smallbox::space::S2;

let num: SmallBox<Any, S2> = smallbox!(1234u32);

if let Some(num) = num.downcast_ref::<u32>() {
    assert_eq!(*num, 1234);
} else {
    unreachable!();
}

容量

容量通过类型参数 Space 的大小表示,无论实际 Space 是什么。

在模块 smallbox::space 中提供了一些空间,从 S1S2S4S64,代表 "n * usize" 空间。

无论如何,您可以定义自己的空间类型,例如字节数组 [u8; 64]。请注意,空间对齐也很重要。如果空间的对齐小于值的对齐,则值将存储在堆上。

基准测试

测试平台是 Intel E3 v1230 v3 上的 Windows 10。

running 6 tests
test box_large_item                  ... bench:         104 ns/iter (+/- 14)
test box_small_item                  ... bench:          49 ns/iter (+/- 5)
test smallbox_large_item_large_space ... bench:          52 ns/iter (+/- 6)
test smallbox_large_item_small_space ... bench:         106 ns/iter (+/- 25)
test smallbox_small_item_large_space ... bench:          18 ns/iter (+/- 1)
test smallbox_small_item_small_space ... bench:           2 ns/iter (+/- 0)

test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out

贡献

欢迎所有类型的贡献。

  • 问题 当您发现错别字、错误或有任何问题时,请随意提出问题。
  • 拉取请求。更好的实现、更多测试、更多文档和错别字修正都欢迎。

许可证

许可协议为以下之一

由您选择。

无运行时依赖

特性