2个不稳定版本
0.2.0 | 2024年1月16日 |
---|---|
0.1.0 | 2024年1月15日 |
#7 in #dynamic-dispatch
10KB
102 行
box_any
一个不带泛型类型的Box包装器,允许动态调度/下转型,但不使用胖指针。
提供了一种动态的盒类型 BoxAny
,其中包含一个 Box<T>
值。 BoxAny
与 Box 类似,但它不使用胖指针进行动态调度。
基准测试
在这个基准测试 bench 中,我们创建了一个由4个不同类型的Vec组成的容器(u8、u16、u32、u64),然后为每个Vec类型插入1M个整数(Vec<u8>, Vec<u16>, Vec<u32>, Vec<u64>
)。为此,我们使用了两种不同的方法
- 动态盒(dyn Trait标准方法):我们创建了一个类型为
Vec<Box<dyn Array>>
的Vec容器,并为每个Vec类型使用downcast + push方法插入1M个整数。 - box_any:我们创建了一个类型为
Vec<BoxAny>
的Vec容器,并为每个Vec类型使用BoxAny downcast + push方法插入1M个整数。
从结果中我们可以看到,使用 BoxAny
方法进行下转型和填充每个Vec比使用 dyn Trait
方法更快。
cargo bench
Finished bench [optimized] target(s) in 0.03s
Running unittests src/lib.rs (target/release/deps/box_any-d326196ff75eb72f)
running 1 test
test tests::test ... ignored
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running benches/bench.rs (target/release/deps/bench-06d6896e0a110c0e)
dyn box checked time: [14.393 ms 14.410 ms 14.431 ms]
change: [-3.8738% -2.8496% -2.0529%] (p = 0.00 < 0.05)
Performance has improved.
Found 10 outliers among 100 measurements (10.00%)
6 (6.00%) high mild
4 (4.00%) high severe
box_any checked time: [5.5236 ms 5.6059 ms 5.7449 ms]
change: [-8.4525% -5.6854% -2.4171%] (p = 0.00 < 0.05)
Performance has improved.
Found 13 outliers among 100 measurements (13.00%)
8 (8.00%) high mild
5 (5.00%) high severe
box_any checked #2 time: [4.2085 ms 4.2173 ms 4.2287 ms]
change: [-6.8000% -6.2270% -5.7308%] (p = 0.00 < 0.05)
Performance has improved.
Found 15 outliers among 100 measurements (15.00%)
5 (5.00%) high mild
10 (10.00%) high severe
示例
use std::any:: TypeId;
use box_any::BoxAny;
let box_u32 = Box::new(032);
let box_string = Box::new(String::from("Hello World"));
let box_any_u32: BoxAny = box_u32.clone().into();
let box_any_string: BoxAny = box_string.clone().into();
let box_any_vec: Vec<BoxAny> = vec![box_any_u32, box_any_string];
assert!(box_any_vec[1].is::<String>());
let string_2: &String = box_any_vec[1].downcast_ref::<String>().unwrap();
assert_eq!(string_2, box_string.as_ref());