#rust
Вопрос:
Допустим , у меня есть массив примитивных целых чисел длины N
, и я хочу создать новый массив той же длины, применив функцию к каждому элементу в исходном массиве. Например, с swap_bytes
помощью метода:
let arr: [u64; 4] = [1, 2, 3, 4];
let output: [u64; 4] = [1u64.swap_bytes(), 2u64.swap_bytes(), 3u64.swap_bytes(), 4u64.swap_bytes()];
// Just an example to show the desired output,
// obviously a generic function wouldn't use this code
Мой вопрос заключается в следующем: было бы быстрее создать выходной массив a [MaybeUninit<u64>; 4]
для начала, или было бы так же быстро инициализировать выходной массив нулями ( [0u64; 4]
), поскольку тип элемента массива является примитивным целым числом?
Поэтому в основном я спрашиваю, какой из этих двух фрагментов кода был бы быстрее и почему:
let arr: [u64; 4] = [1, 2, 3, 4];
let mut out = MaybeUninit::uninit_array::<4>();
for i in 0..4 {
out[i] = MaybeUninit::new(arr[i].swap_bytes());
}
MaybeUninit::array_assume_init(out)
или
let arr: [u64; 4] = [1, 2, 3, 4];
let mut out = [0u64; 4];
for i in 0..4 {
out[i] = arr[i].swap_bytes();
}
out
Комментарии:
1. на этот вопрос нет однозначного ответа, может ли компилятор оптимизировать его или нет.
2. Если компилятор не оптимизирует операцию обнуления, то это ненужная операция, которой
MaybeUninit
версия избежала бы.3. IME , делая
for (d, s) in out.iter_mut().zip(amp;arr) { *d = *s }
это , компилятор оптимизирует нулевую инициализацию.4. И действительно, на игровой площадке нулевая инициализация также оптимизирована из версии OP .