Почему «двигаться» в Rust на самом деле не двигается? - PullRequest
0 голосов
/ 25 ноября 2018

В приведенном ниже примере:

struct Foo {
    a: [u64; 100000],
}

fn foo(mut f: Foo) -> Foo {
    f.a[0] = 99999;
    f.a[1] = 99999;
    println!("{:?}", &mut f as *mut Foo);

    for i in 0..f.a[0] {
        f.a[i as usize] = 21444;
    }

    return f;
}
fn main(){
    let mut f = Foo {
        a:[0;100000]
    };

    println!("{:?}", &mut f as *mut Foo);
    f = foo(f);
    println!("{:?}", &mut f as *mut Foo);
}

Я обнаружил, что до и после перехода в функцию foo адрес f отличается.Почему Rust копирует такую ​​большую структуру везде, но не перемещает ее (или не выполняет эту оптимизацию)?

Я понимаю, как работает стековая память.Но с информацией, предоставленной собственностью в Rust, я думаю, что копию можно избежать.Компилятор излишне копирует массив дважды.Может ли это быть оптимизацией для компилятора Rust?

1 Ответ

0 голосов
/ 25 ноября 2018

Ход - это memcpy, за которым следует трактовать источник как несуществующий.

Ваш большой массив находится в стеке.Именно так работает модель памяти Rust: локальные переменные находятся в стеке.Поскольку пространство стека foo исчезает при возврате функции, компилятор ничего не может сделать, кроме как скопировать память в пространство стека main.

В некоторых случаях компилятор может переставитьтакие вещи, что движение может быть исключено (источник и место назначения объединены в одно), но это оптимизация, на которую нельзя положиться, особенно для больших вещей.

Если вы не хотите копироватьОгромный массив вокруг, выделите его в кучу самостоятельно, либо через Box<[u64]>, либо просто используя Vec<u64>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...