2016-06-28 9 views
2
struct Vec { 
    data: [f32; 3], 
} 

impl Vec { 
    fn dot(&self, other: &Vec) -> f32 { 
     .. 
    } 
    // vs 
    fn dot(self, other: Vec) -> f32 { 
     .. 
    } 
} 

現在ベクトル計算ライブラリを作成しており、ベクタータイプを借りてコピーする必要があるかどうかは疑問です。小さなデータ型を借りたりコピーしたりする必要がありますか?

現時点では、を常時書き込む必要がないため、Vecの場合はCopyを実装しています。これによりAPIが少し良くなります。

しかし、すべての制約もCopyを満たす必要があるため、より複雑な制約が必要です。

パフォーマンスを向上させる可能性があるのはなぜですか?

人間工学的に優れている可能性があるのはなぜですか?

編集:私が作成した

microbenchmark

test bref_f32 ... bench: 2,736,055 ns/iter (+/- 364,885) 
test bref_f64 ... bench: 4,872,076 ns/iter (+/- 436,928) 
test copy_f32 ... bench: 2,708,568 ns/iter (+/- 31,162) 
test copy_f64 ... bench: 4,890,014 ns/iter (+/- 553,050) 

小さなパフォーマンスの面で、この例のrefcopy差がないようです。

Copyは、ライブラリユーザーにとってより人間工学的に優れているようです。

+2

あなたは、「慣用的」ではなく「パフォーマンス」または「境界を簡素化」についてお聞きしたい本当によろしいですか?イディオムは非常に*主観的なので、私は両方の選択肢が推奨されることがあり、明確な客観的な答えが存在しないことを恐れています....あなたの質問は、閉鎖のために準備されています(主に意見ベース)。 @MatthieuM。 –

+0

。私は慣用錆コードがどのように見えるべきかについていくつかのガイドラインがあると仮定し、質問を言い換えて例を追加しました。 –

答えて

1

錆のようになります推測することは崇高な美学を目標と純粋な学術的言語と特異目的ではありません。錆は、プラグマティズムを意味するシステムプログラミング言語です。

親指の一般的なルールは、あなたのインターフェイスが正しく所有権文書化すべきであるということです:あなたは一時的に所有権を放棄したときに参照(おそらく変更可能)によって所有

  • パスをあきらめたときに値によって

    • パスを

    しかし、Copyの形質は遊びでのプラグマティズムの完璧な例です。参照渡しは煩雑になる可能性があります(誰でも(&1 + &x) * &yと入力したいと思いますか?)ので、アフィンである必要のないタイプのエスケープハッチが作成されます(つまり、特別な処理は不要です)。あなたのタイプははその後、そのようにマーキング、こととCopyを維持するを保証できる場合

    その結果、意味的に、ユーザーに人間工学を向上させることができ、その使用上の余裕を与えます。後でCopyの特性を削除することは、後方互換性のない変更であることを思い出させるが、それをマークすることをお勧めします。

    タイプがCopyになると、私はその事実を利用して値を渡すことをためらっていません。結局のところ、型が値渡されない場合は、最初にCopyにするという意味はありません。


    唯一の注意点はパフォーマンスの理由です。

    Copyではありません。はコピーを強制します。これは、オプティマイザがコピーを使用するためのすべての緯度を持っていることを意味します。

    小型タイプではパフォーマンスが起こるものは何でも大きく異なることはほとんどありません。より大きなタイプの場合、パフォーマンスが重要であれば、さまざまなインターフェースのベンチマークを推奨します。 Vecは、64ビットアーキテクチャ上のポインタ/リファレンスのサイズのわずか1.5倍なので、実際には灰色の領域にあります。時々コピーが遅くなる(より大きなコピー)が、時にはローカルコピーを持つ利点は、ポインタではトリガされない最適化を可能にする。

    しかし、このようなベンチマークは、関数がインライン化されているかどうかに大きく依存するため、危険に満ちています(コピーを削除する余裕がある程度)。

  • 4

    所有権のように思われないため、このシナリオでの借用をお勧めします。だから、私はあなたのコードは

    struct Vec { 
        data: [f32; 3], 
    } 
    
    impl Vec { 
        fn dot(&self, other: &Vec) -> f32 {..} 
    } 
    
    +1

    あなたはそれをお勧めする理由を説明できますか? –

    +0

    新しいベクトル全体を作成するために、より多くのメモリを使用するので、私はそれをお勧めします。新しいベクターを作成する必要がない場合は、作成しないでください。 –

    +1

    *ベクトルをコピーすると何が起こるか* - 最適化コンパイラの気まぐれになる可能性があり、単純化できると判断した場合。 – Shepmaster

    関連する問題