有没有一种方法可以进行预&释放价值? [英] Is there a way to pre- & un-leak a value?
问题描述
我目前正在研究对数组做更多的事情,但是我认为如果允许我们以某种方式预先转换为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.
这篇关于有没有一种方法可以进行预&释放价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!