web-dev-qa-db-ja.com

Swiftをこれらの比較でObjective-Cよりもはるかに高速にするにはどうすればよいですか?

Appleは新しいプログラミング言語 Swift at WWDC14 を発表しました。プレゼンテーションでは、Objective-CとPythonのパフォーマンスを比較しました。以下は、スライドの1つで、複雑なオブジェクトの並べ替えを実行する3つの言語を比較した図です。

enter image description here

RC4 暗号化アルゴリズムを使用したパフォーマンス比較について、さらに驚くべきグラフがありました。

明らかにこれはマーケティングの話であり、彼らはこれがそれぞれにどのように実装されているかについて詳細には触れませんでした。しかし、私は疑問に思います:

  1. 新しいプログラミング言語はどのようにしてはるかに速くなりますか?
  2. Objective-Cの結果はコンパイラの不良が原因ですか、それともSwiftよりもObjective-Cで効率が悪いものがありますか?
  3. 40%のパフォーマンス向上をどのように説明しますか?ガベージコレクション/自動参照制御によって追加のオーバーヘッドが発生する可能性があることを理解していますが、これだけですか?
117
Yellow

まず、(IMO)とPythonとの比較はほとんど意味がありません。Objective-Cとの比較だけが意味があります。

  • 新しいプログラミング言語はどのようにしてはるかに速くなりますか?

Objective-Cは遅い言語です。 (C部分のみが高速ですが、それはCだからです)極端に高速になったことはありません。それは彼らの(Appleの)目的には十分速く、古いバージョンよりも高速でした。そしてそれは遅かった...

  • Objective-Cは悪いコンパイラーから生じますか、それともObjective-CにはSwiftよりも効率の悪いものがありますか?

Objective-Cは、すべてのメソッドが動的にディスパッチされることを保証しました。静的ディスパッチはまったくありません。そのため、Objective-Cプログラムをさらに最適化することは不可能でした。まあ、JITテクノロジーが役立つかもしれませんが、私の知る限り、Appleは予測できないパフォーマンス特性とオブジェクトの寿命を本当に嫌っています。JITのものを採用したとは思いません。Swiftには、Objective-C互換性のために特別な属性を指定しない限り、このような動的なディスパッチ保証はありません。

  • 40%のパフォーマンス向上をどのように説明しますか?ガベージコレクション/自動参照制御によって追加のオーバーヘッドが発生する可能性があることを理解していますが、これだけですか?

GCやRCはここでは関係ありません。 Swiftも主にRCを採用しています。GCはありません。また、GCテクノロジーに大きなアーキテクチャ上の飛躍がない限り、そうではありません。(IMO、それは永遠です)私は信じていますSwiftには静的最適化の余地が非常にあり、特に低レベルの暗号化アルゴリズムは、通常、巨大な数値計算に依存しているため、静的にディスパッチする言語にとっては非常に有利です。

実は40%は小さすぎてビックリしました。私ははるかに期待していました。とにかく、これは最初のリリースであり、最適化は主な関心事ではなかったと思います。 Swiftは完全な機能でもありません!彼らはそれをより良くします。

更新

GCテクノロジーの方が優れていると主張するように私を悩ませている人もいます。以下のものは議論の余地があるかもしれませんが、私の非常に偏った意見ですが、私はこの不要な議論を避けるために言わなければならないと思います。

保守的/トレース/世代別/増分/並列/リアルタイムGCとは何か、それらがどのように異なるかを知っています。ほとんどの読者もすでにそれを知っていると思います。また、GCは一部の分野では非常に優れており、場合によっては高いスループットを示すことにも同意します。

とにかく、GCスループットの主張は常にRCよりも優れていると思います。 RCのオーバーヘッドの大部分は、参照カウント操作と、参照カウント数変数を保護するためのロックによるものです。また、RC実装は通常、操作のカウントを回避する方法を提供します。 Objective-Cには__unsafe_unretainedとSwiftでは(まだはっきりしていませんが)unownedもの。参照カウントの運用コストが許容できない場合は、メカニズムを使用して、それらを選択的にオプトアウトすることができます。理論的には、非保持参照を非常に積極的に使用してRCオーバーヘッドを回避することにより、ほぼ一意の所有権シナリオをシミュレートできます。また、コンパイラーが明らかな不要なRC操作を自動的に削除できることも期待しています。

RCシステム、AFAIKとは異なり、reference-typesの部分的なオプトアウトはGCシステムのオプションではありません。

GCベースのシステムを使用している多くのリリースされたグラフィックスとゲームがあり、それらのほとんどが決定論の欠如によって苦しんでいることも知っています。パフォーマンス特性だけでなく、オブジェクトのライフタイム管理も行います。 Unityは主にC++で書かれていますが、小さなC#の部分がすべての奇妙なパフォーマンスの問題を引き起こしています。 HTMLハイブリッドアプリであり、どのシステムでも予測不可能なスパイクが発生しています。広く使用されていても、それが優れているとは限りません。それは、それが多くのオプションを持たない人々にとって簡単で人気があることを意味します。

アップデート2

ここでも、不必要な議論や議論を避けるために、もう少し詳しく説明します。

@Asikは、GCスパイクについて興味深い意見を述べました。 value-type-everywhereアプローチは、GCをオプトアウトする方法と見なすことができます。これはかなり魅力的で、一部のシステムでも実行できます(たとえば、完全に機能的なアプローチ)。これは理論的にはニースであることに同意します。しかし、実際にはいくつかの問題があります。最大の問題は、このトリックを部分的に適用しても、スパイクのない真の特性が得られないことです。

レイテンシの問題は常にall or nothingの問題だからです。 1フレームのスパイクが10秒間(= 600フレーム)ある場合、システム全体が明らかに失敗しています。これはどれほど良いか悪いかではありません。合格または不合格です。 (または0.0001%以下)では、GCスパイクの原因はどこにあるのでしょうか。これはGC負荷の分散が悪いです。そしてそれは、GCが根本的に不確定であるためです。ガベージを作成すると、GCがアクティブになり、最終的にスパイクが発生します。もちろん、GC負荷が常に理想的な理想的な世界では、これは起こりませんが、私は架空の理想的な世界ではなく、現実の世界に住んでいます。

次に、スパイクを回避する場合は、システム全体からall ref-typesを削除する必要があります。しかし、それは難しく、非常識で、.NETコアシステムやライブラリなどの取り外しできないパーツのために不可能ですらあります。 非GCシステムを使用する方がはるかに簡単です

GCとは異なり、RCは基本的に決定論的であり、スパイクを回避するためだけにこの非常識な最適化(純粋な値型のみ)を使用する必要はありません。あなたがしなければならないことは、スパイクを引き起こす部分を追跡して最適化することです。 RCシステムでは、スパイクはローカルアルゴリズムの問​​題ですが、GCシステムでは、スパイクは常にグローバルシステムの問題です。

私の答えはあまりに話題外になりすぎていると思います、そしてほとんどは既存の議論の繰り返しです。 GC/RCの優れている点、劣っている点、またはその他の点について本当に主張したい場合は、このサイトとStackOverflowで多くの既存の議論が行われているので、そこで戦い続けることができます。

62
Eonil

Pythonの3.9倍の速さで、かなりのマージンでほとんどのベンチマークを一貫して失っている言語です(そう、Perlと同等ですRubyおよびPHP;静的に入力されたものはすべて失います)。自慢するべきです。

ベンチマークゲーム は、多くの場合pythonプログラムよりも桁違いに速いC++プログラムを示しています。Java、C#(on Mono)、OCaml、Haskell、さらには静的に型付けされていないClojureです。

したがって、本当の問題は、Objective-CがPythonよりも2.8倍だけ速いということです。どうやら、彼らは慎重にベンチマークを選択しましたが、ObjCのゆっくりと完全に動的なディスパッチは多くのことを傷つけます。静的に型付けされた言語は、もっとうまくできるはずです。複雑なオブジェクトの並べ替えでは、オブジェクトを比較するための多くのメソッド呼び出しがあり、実際の比較はおそらくそれほど複雑ではありませんでした。したがって、Swiftが少なくとも型情報の利点を活用する場合、メソッドの呼び出しは簡単に改善でき、ObjCの方が優れている可能性がある他の操作は十分ではありません。

もちろん、 ベンチマークゲーム が明確に示しているように、さまざまなタスクの相対的なパフォーマンスは大きく変動するため、1つのベンチマークは実際には代表的ではありません。ベンチマークがあり、大きな利点がある場合は、代わりに1つを示していたので、他のタスクでは、おそらくそれほど良くないか、それほど多くありません。

72
Jan Hudec

Objective-Cは、すべてのメソッド呼び出しを動的にディスパッチします。

Hypothesis:ベンチマークは静的型付けを使用して、Swiftコンパイラーがcompareループからsortメソッドをルックアップするようにします。これはComplexのサブクラスではなく、配列内のComplexオブジェクトのみを許可する狭い型の制限が必要です。

(Objective-Cでは、言語ランタイムサポートを呼び出してメソッドポインターを検索することで、必要に応じて手動でメソッドルックアップを引き上げることができます。配列内のすべてのインスタンスが非常に同じクラスであることを確認してください。 。)

仮説: Swiftは、ループからの参照カウント呼び出しを最適化します。

Hypothesis: SwiftベンチマークはObjective-Cオブジェクトの代わりにComplex構造体を使用するので、ソート比較は動的メソッドディスパッチを必要としません(それができないため)サブクラス化される)または参照カウント作業(値型であるため)。

(Objective-Cでは、Objective-Cオブジェクトを含まない限り、パフォーマンスのためにC/C++にフォールバックできます(構造体のC配列をソートするなど)。

5
Jerry101

正直なところ、彼らが使用しているテストにソースをリリースしない限り、私は何も信用しませんAppleこの件について言わなければなりません。これは、PPCは、電力問題に基づいて6か月前にIntelがコマーシャルでIntelバニーを吸い、実際にトーチングしたと言っていました。私は、Swift並べ替えよりも多くのカテゴリでObjCよりも高速です。

さらに、WWDCでリリースされている統計には、マーケティングの匂いがあるため、質問する必要があります。

言われていることのすべては、私がSwiftとObjCの間でテストを実行していないことですが、私が知っていることからSwiftは独自のLLVM IR拡張とそれを持っていますObjCよりもコンパイル時に多くの最適化が行われている可能性があります。

完全な開示:オープンソースを作成していますSwiftコンパイラは https://ind.ie/phoenix/ にあります==

SwiftがAppleハードウェアで利用できないだけではないことを確認してください。

3
greg.casamento

私はSwiftチュートリアルで苦労してきましたが、Swiftは、より現実的な(Visual Basicについて考えるようになります) Objective-Cよりも 'object-ification'。CまたはC++を考慮に入れていた場合、コンパイル時間がさらに長いため、後者が勝ったと思います。

この場合、私はObjective-Cがそのオブジェクト指向の純粋さ(およびオーバーヘッド)の犠牲者であると思います。

0
Painted Black