最简单的方法来专门化代码常量在 rust ?

xa9qqrwz  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(110)

假设我有一个这样的循环,其中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!()
  }
}

有没有更好的方法来专门化到特定的顺序值?

wwwo4jvm

wwwo4jvm1#

确实有更好的方法来专门化常量值!常量泛型于2021年中期在Rust 1.51中发布。
我的原始代码的改进版本更简单,实现了相同的性能,并且具有更小的二进制大小:

fn cumulative_sum_internal<const ORDER: usize>(xs: Vec<i64>) {
   ... // same logic as before
}

pub fn cumulative_sum(xs: Vec<i64>, order: usize) {
  match order {
    1 => cumulative_sum_internal::<1>(xs),
    2 => cumulative_sum_internal::<2>(xs),
    3 => cumulative_sum_internal::<3>(xs),
    _ => panic!()
  }
}

相关问题