假设我有一个这样的循环,其中xs.len()
很大,order <= 3
:
pub fn cumulative_sum(xs: Vec<i64>, order: usize) {
let mut res = Vec::with_capacity(xs.len());
let mut moments = vec![0; order];
for i in 0..xs.len() {
res.push(moments[0]);
for o in 0..order - 1 {
moments[o] += moments[o + 1];
}
moments[order - 1] += xs[i];
}
}
我发现我可以通过专门使用一个编译时常量来处理order,使速度提高2倍,但是我目前的代码相当令人不快。
trait CompileTimeOrder {
const ORDER: usize;
}
macro_rules! impl_order {
($name: ident, $order: expr) => {
struct $name;
impl CompileTimeOrder for $name {
const ORDER: usize = $order;
}
}
}
impl_order!(Order1, 1);
impl_order!(Order2, 2);
impl_order!(Order3, 3);
fn cumulative_sum_internal<O: CompileTimeOrder>(xs: Vec<i64>) {
let order = O::ORDER;
... // same logic as before
}
pub fn cumulative_sum(xs: Vec<i64>, order: usize) {
match order {
1 => cumulative_sum_internal::<Order1>(xs),
2 => cumulative_sum_internal::<Order2>(xs),
3 => cumulative_sum_internal::<Order3>(xs),
_ => panic!()
}
}
有没有更好的方法来专门化到特定的顺序值?
1条答案
按热度按时间wwwo4jvm1#
确实有更好的方法来专门化常量值!常量泛型于2021年中期在Rust 1.51中发布。
我的原始代码的改进版本更简单,实现了相同的性能,并且具有更小的二进制大小: