Obecnie patrzę na doing more stuff with arrays, ale myślę, że wydajność tych operacji mogłaby być jeszcze lepsza, gdybyśmy mogli w jakiś sposób przetransformować do przodu tablicę z przodu, tylko po to, by ją przeciekać, gdy funkcja się zakończy. To pozwoliłoby nam na użycie wzmacniacza wycieku bez a) wprowadzania bezpieczeństwa i b) konfigurowania catch_panic(_)
. Czy jest to w jakiś sposób możliwe w Rust?Czy istnieje sposób na pre- i nieszczelność wartości?
Na przykład, tworząc ogólną tablicę z iteratora (to oczywiście nie działa):
#[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)
}
}
Należy zauważyć, że jeśli my albo miał czasu kompilacji dostępu do wielkości T
lub typu, może ukryć swoje wnętrzności przed wypożyczeniem (jak w przykładzie Leaked<T>
), jest to całkowicie wykonalne.
Jaka jest poprawa wydajności, której się spodziewacie? Nie zwiększasz 'len'? – malbarbo
Jeśli próbuję zapobiec wyciekom przez łapanie paniki (która działa tylko na razie w wersji beta/nocnej), otrzymuję o 45% więcej przepustowości niż zbieranie w 'Vec'. Zakładam, że mogę uzyskać jeszcze lepsze wyniki przed wyciekiem. – llogiq