Вот этот очень простой код потенциально легко вызовет stack overflow (если нет, то надо просто увеличить 16777216), хотя не должен (мы ведь на самом деле выделяем место в куче в итоге).
#[derive(Copy, Clone)]
pub struct Item {
a: i32,
b: i32
}
pub struct Items {
items: [Item; 16777216]
}
impl Items {
pub fn new() -> Items {
Items {
items: [Item { a: 0, b: 1 }; 16777216]
}
}
}
fn foo() -> Box<Items> {
Box::new(Items::new())
}
Пруф: https://rust.godbolt.org/z/8sWsoKojx
Для Ъ: Массив сначала создаётся на стеке, а только потом выделяется память и происходит memcpy в кучу. Максимальные оптимизации не спасут.
К тому же не забываем про оверхед копирования. Я готов поверить разработчикам Rust, что копирование при создании структур из нескольких сотен байт не создаст заметной просадки, но я верю, что пример выше будет статистически значимо работать медленнее уже на нескольких тысячах элементов, а не обязательно 16 миллионов.
Как принято создавать в Rust такие массивы? unsafe или есть решения получше?
Мне нравится Rust последнее время, сколько я к нему присматриваюсь, но вот такая очевидная мелочь как copy elision не предусмотрена для типа системного языка... Или я просто всё делаю не так и Items::new надо писать как-то иначе?