有没有一种方法可以进行预&释放价值? [英] Is there a way to pre- & un-leak a value?

查看:111
本文介绍了有没有一种方法可以进行预&释放价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究对数组做更多的事情,但是我认为如果允许我们以某种方式预先转换为Leaked<T>数组,而仅在函数结束时释放该数组,则这些操作的性能会更好.这将使我们可以使用泄漏放大,而无需a)引入不安全性和b)设置catch_panic(_).在Rust中这有可能吗?

I'm currently looking into doing more stuff with arrays, but I think the performance of those operations could be even better if we were allowed to somehow transmute into a Leaked<T> the array up front, only to un-leak it when the function ends. This would let us use leak amplification without a) introducing unsafety and b) setting up a catch_panic(_). Is this somehow possible in Rust?

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

For example, creating a generic array from an iterator (this obviously does not work):

#[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的大小,或者可以将其内脏隐藏在rowck中的类型(例如示例中的Leaked<T>),那么这是完全可行的. >

I should note that if we either had compile-time access to the size of T or a type that can hide its innards from borrowck (like Leaked<T> in the example), this is perfectly feasible.

推荐答案

可以使用 nodrop ,但它可能会泄漏.

It is possible using nodrop, but it could leak.

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

让我们假设在从i中消耗掉第一项(a)并将其写入r之后,会发生恐慌. i中的其余项目将被删除,而a中的项目则不会被删除.尽管不认为泄漏内存不安全,但这不是可取的.

Let's suppose that after the first item (a) is consumed from i and written to r, a panic happens. The remaining items from i would be drop, but the item a would not. Although leaking memory is not considered unsafe, it is not desirable.

我认为问题链接中描述的方法是必经之路.它类似于 Vec ArrayVec 实现.我在写的数组库中使用了类似的方法.

I think that the approach described in the question link is the way to go. It is similar to the Vec and ArrayVec implementations. I'm using a similar approach in array library that I'm writing.

这篇关于有没有一种方法可以进行预&amp;释放价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆