#dynamic-dispatch #dynamic #box #downcast #dispatch #any

box_any

提供了一种动态的盒类型 BoxAny,其中包含一个 Box<T> 值。 BoxAny 与 Box 类似,但它不使用胖指针进行动态调度。

2个不稳定版本

0.2.0 2024年1月16日
0.1.0 2024年1月15日

#7 in #dynamic-dispatch

MIT 许可证

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());

无运行时依赖