2016-07-21 8 views
1

錆の中でVecを初期化することは、他の言語と比較すると非常に遅いです。たとえば、次のコードVecの初期化時間を改善するにはどうすればよいですか?

let xs: Vec<u32> = vec![0u32, 1000000]; 

は回百万1

let xs: Vec<u32> = Vec::new(); 
xs.push(0); 
xs.push(0); 
xs.push(0); 
// ... 

にを変換します。これをCの次のコードと比較すると、

uint32_t* xs = calloc(1000000, sizeof(uint32_t)); 

という違いがあります。

は、私はそれはまだ非常に遅いです

let xs: Vec<u32> = Vec::with_capacity(1000000); 
xs.resize(1000000, 0); 

ビットでもう少し運を持っていました。

Vecを早く初期化する方法はありますか?

+5

Rustプログラムをどのようにコンパイルしましたか? '--release'フラグを渡しましたか? (これは最適化を有効にします) – BurntSushi5

+6

私が間違っている場合は私を修正しますが、100万個のゼロサイズの要素の配列を割り当てる 'calloc'呼び出しではありませんか? manページは、これを実行すると何も*割り当てられないので、もちろん違いは目立つでしょう... –

+3

ソースをチェックすると、 'vec![0u32、1000000]'は100万コールにコンパイルされませんプッシュする。基本的に 'Vec :: with_capacity' +' Vec :: resize'にコンパイルされます。 – mcarton

答えて

7

実際には異なる操作を実行しています。 Rustでは、100万の0の配列を割り当てています。 Cでは、長さがゼロの要素(つまり、存在しない要素)が100万個ある配列を割り当てています。 DKがあなたの質問にコメントして指摘したように、これは実際には何もしないと私は信じていません。

また、コードを実行すると、最適化するときにラップトップコンピュータで非常に匹敵する時間が得られましたが、これはおそらくRustのベクトル割り当てが最適化されているためです。

cargo build --release 
time ../target/release/test 

real 0.024s 
usr 0.004s 
sys 0.008s 

及びC:--releaseなし

gcc -O3 test.c 
time ./a.out 

real 0.023s 
usr 0.004s 
sys 0.004s` 

、さび性能が割り当てが実際に起こるおそらくので、低下します。 calloc()は、メモリが最初にゼロにされているかどうかを調べ、既にゼロに設定されている場合はメモリをリセットしないことに注意してください。これにより、実行時間はcalloc()となり、以前の状態に多少依存します。

+1

問題は、私が '--release'フラグを使用していなかったことです。このフラグを使用すると速くなりました。私の質問では、 'vec!'マクロがたくさんの 'push()'呼び出しを生成するという誤った仮定をしていましたが、これは真実ではありません。だから私はこの答えを受け入れています。 –

+0

ああ、そうです。私は編集するために私の編集を元に戻します。 cargo.tomlファイルで最適化される内容を正確に設定することもできます。 –

+0

これは正接ですが、 "calloc()もメモリが最初にゼロ化されているかどうかを調べる"の参照がありますか?それを実際にゼロ化するよりも、時間を短縮してどのようにチェックできますか? –

関連する問題