2016-12-22 6 views

答えて

2

私が理解しているように、ヒープとは対照的に、スタックに格納されているため、スウィフトの値タイプはより効果的です。

時には。しばしば。たとえば、Stringにはヒープ割り当てストレージが含まれます。多くの値型には、ヒープ割り当てストレージが隠されています(実際は、実際には共通です)。だから、あなたは多くのタイプで期待しているパフォーマンスの向上を得られていないかもしれませんが、多くの場合、クロージャによってもそれを失うことはありません。

値の種類は、パフォーマンスではなく動作に関するものです(もちろん、value types and value semanticsを区別する必要がありますが、パフォーマンスに影響を与える可能性があります)。値の型とDispatchQueueについての良い点は、独自の独立したコピーがあることを知っているので、複数のキューの値を誤って変更することはないということです。キューにディスパッチするオーバーヘッド(最適化されていますが、安価ではありません)を支払うまでには、値タイプをコピーするための余分なコストはおそらく大きな問題ではありません。

私の経験では、特にCopy-On-Writeによる最適化のために、Swiftのパフォーマンスを考えるのは非常に困難です。しかし、明らかな「値型」が内部参照型を隠すことができるという事実も、パフォーマンス分析を非常に難しくしています。変更される可能性のある内部の詳細を知り、頼りにしなければならないことがよくあります。スウィフトパフォーマンスの周りに頭を浮かべるには、確かにUnderstand Swift Performance(おそらく数回)を見てください。あなたがC++からのパフォーマンスの直感を持っているなら、あなたはSwiftのためにそれをほとんどすべて投げなければなりません。それはちょっとだけ違ったことをします。

1

パフォーマンスメトリックと最適化の見解がSwiftモデルと完全に一致していないと思われます。

まず、その点を正しく把握しているように見えますが、一般的に「スタック割り当て」と「ヒープ割り当て」という言葉は誤解を招きます。値型は参照型の一部であり、ヒープ上に存在することができます。同様に、おそらくヒープに行くものは本当にヒープに行く必要はありません。参照カウントを必要としない参照カウントオブジェクトは、気づかずにスタックに割り当てられます。 C++のような他の言語では、preferred terminologyは「自動ストレージ」(「スタック」)と「ダイナミックストレージ」(「ヒープ」)です。もちろん、Swiftはこれらの概念を持っていません(値型と参照型のみを持ちます)が、パフォーマンス特性を記述するのに便利です。

エスケープクロージャは、スタックフレームに寿命を掛けることができないため、動的ストレージが必要です。ただし、クロージャーは常に割り当てられ、クロージャーは任意の数の値に対してストレージを持つことができるため、キャプチャーする必要のある変数の数にかかわらず、エスケープクロージャーを使用する関数を呼び出すために支払うパフォーマンス価格は均一です。

つまり、取得された値型オブジェクトはすべて、1回の動的割り当てでグループ化され、メモリ割り当てのパフォーマンスコストは、要求している量に比例しません。したがって、クロージャ自体をエスケープするのに関連する(小さな)スピードコストがあると考えるべきですが、そのコストはクロージャがキャプチャする値の数に比例しません。やむを得ない先行コストとは別に、バリュー・タイプのパフォーマンスの低下もないはずです。

さらに、Robは言ったように、(文字列、配列、辞書、セットなどの)すべての重要でない値の型は、実際には参照型へのラッパーであるため、これらのオブジェクトの値型は、最初のパフォーマンスの優位性。

関連する問題