2016-04-28 9 views
5

私は現在doing more stuff with arraysを探していますが、何らかの形で配列が先頭に配列されていて、関数が終了したときにそれをun-leakすることが許可されていれば、その操作のパフォーマンスはさらに良くなると思います。これは、a)不安全性を導入し、b)catch_panic(_)を設定することなく、漏出増幅を使用させる。これは何とかRustで可能ですか?例えば値をプリ&リークする方法はありますか?

、反復子(これは明らかに動作しません)から、一般的な配列の作成:私たちのどちらかがTのサイズや種類にアクセスする時にコンパイルがあった場合に注意すべきである

#[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) 
    } 
} 

をこの例ではLeaked<T>のように内部を隠すことができますが、これは完全に実行可能です。

+0

期待どおりのパフォーマンス向上はありますか? 'len'をインクリメントしませんか? – malbarbo

+0

パニックをキャッチすることで漏れを防止しようとすると(これはベータ/ナイトリックでのみ動作します)、Vecに収集するよりもスループットが約45%向上します。私は前漏れによってさらに良い結果を得ることができると推測します。 – llogiq

答えて

3

nodropを使用することは可能ですが、漏れる可能性があります。

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 : NoDrop<GenericArray<T, N>> = NoDrop::new(std::mem::uninitialized()); 
     let i = list.into_iter(); 
     for r in res.iter_mut() { 
      // this could panic anytime 
      std::ptr::write(r, f(i.next().unwrap())) 
     } 
     res.into_inner() 
    } 
} 

パニックが起こる、のは、最初の項目(a)後iから消費され、rに書かれたと仮定しましょう。 iの残りのアイテムはドロップされますが、アイテムaは削除されません。メモリの漏れは安全ではないと考えられますが、望ましくありません。

私は、質問リンクに記載されているアプローチは行く方法だと思います。これは、VecArrayVecの実装に似ています。私は書いている配列ライブラリで同様のアプローチを使用しています。

+0

ありがとう!それはまさに私が探していたものです。 – llogiq

+1

@llogiq興味があれば、私はこの種の構造を漏らさないように他の質問に答えるいくつかのコードを書いた。 http://stackoverflow.com/questions/36925673/how-can-i-initialize-an-array-using-a-function – malbarbo

+0

もう一度おねがいします - それは私が思いついたものとほとんど同じです。私のベンチマークは非常に有望でもあります。 – llogiq

関連する問題