【问题标题】:Is there a way to pre- & un-leak a value?有没有办法预先和取消泄漏值?
【发布时间】:2016-04-28 15:59:46
【问题描述】:

我目前正在研究doing more stuff with arrays,但我认为如果我们被允许以某种方式预先转换为Leaked<T> 数组,那么这些操作的性能可能会更好,只是在功能结束。这将让我们使用泄漏放大,而不会 a) 引入不安全性和 b) 设置 catch_panic(_)。这在 Rust 中是否可能?

例如,从迭代器创建一个泛型数组(这显然行不通):

#[inline]
fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        // pre-leak the whole array, it's uninitialized anyway
        let mut res : GenericArray<Leaked<T>, N> = std::mem::uninitialized();
        let i = list.into_iter();
        for r in res.iter_mut() {
            // this could panic anytime
            std::ptr::write(r, Leaked::new(f(i.next().unwrap())))
        }
        // transmuting un-leaks the array
        std::mem::transmute::<GenericArray<Leaked<T>, N>,
                              GenericArray<T, N>>(res)
    }
}

我应该注意,如果我们可以在编译时访问 T 的大小或可以隐藏其内部结构的类型(如示例中的 Leaked&lt;T&gt;),这是完全可行的。

【问题讨论】:

  • 您期望的性能改进是什么?不增加len
  • 如果我试图通过捕捉恐慌来防止泄漏(目前它只适用于 beta/nightly),我得到的吞吐量比收集到 Vec 的吞吐量高出大约 45%。我想我可以通过预泄漏获得更好的结果。

标签: memory-leaks rust


【解决方案1】:

可以使用nodrop,但可能会泄漏。

fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
     unsafe {
        // pre-leak the whole array, it's uninitialized anyway
        let mut res : NoDrop<GenericArray<T, N>> = NoDrop::new(std::mem::uninitialized());
        let i = list.into_iter();
        for r in res.iter_mut() {
            // this could panic anytime
            std::ptr::write(r, f(i.next().unwrap()))
        }
        res.into_inner()
    }
}

假设在第一个项目 (a) 从 i 消耗并写入 r 之后,发生了恐慌。来自i 的剩余项目将被丢弃,但项目a 不会。虽然泄漏内存is not 被认为是不安全的,但这是不可取的。

我认为问题链接中描述的方法是可行的方法。它类似于VecArrayVec 实现。我正在编写的数组库中使用了类似的方法。

【讨论】:

  • 谢谢!这正是我想要的。
  • @lllogiq 如果您感兴趣,我写了一些代码来回答其他问题,使这种构造不会泄漏。见stackoverflow.com/questions/36925673/…
  • 再次感谢 - 这与我想出的差不多。我的基准测试也很有希望——非常接近于简单的数组构造。
猜你喜欢
  • 2010-10-11
  • 2020-09-29
  • 2012-11-20
  • 2012-08-22
  • 1970-01-01
  • 2019-06-25
  • 2019-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多