AndroidデバイスでのXamarin(monodroid)とJava(DalvikVM)のパフォーマンス比較

画像

こんにちは 多くの人が、AndroidまたはiOSでのXamarinのパフォーマンスの違いに興味を持っています。 現時点ではiOSの質問は開いたままにしますが、monodroidのパフォーマンスに関するすべての質問を一度だけ閉じることを提案します。



多くの場合、これらの質問は、モノドロイドがどのように機能するかについての誤解が原因で発生します。たとえば、「XamarinはJVMで再構築しますか?」などの質問がありました。 これは確かにそうではありません。 Xamarinは、Android Dalvik仮想マシンと同じレベルのAndroidで実行されることを理解することが重要です。 したがって、パフォーマンスを比較する場合、実際には2つの仮想マシン(Mono VMとDalvik VM)のパフォーマンスを比較します。





検証方法



パフォーマンステストには、C#で実装する必要がある、Javaで実装され、一般に認識されているメソッドが必要です。 まず、よく知られているLINPACKパフォーマンステストを使用することにしました。そのソースコードはオープンであり、C#バージョンを簡単に実装できるためです。



LINPACKパフォーマンステストは、浮動小数点コンピューティングシステムの速度を評価することによりパフォーマンスを評価する方法です。 ベンチマークはJack Dongarraによって作成され、コンピューターがLU分解法を使用して次元N x Nの高密度SLAU Ax = Bの解を検索する速度を測定します。 解は、2/3 * N 3 + 2 * N 2の浮動小数点演算が実行される主要要素( description )を選択して、ガウス法によって取得されました。 結果は、1秒あたりの浮動小数点演算(MFLOP / s、多くの場合FLOPSのみ)で定義されます。 パフォーマンステスト自体は、LINPACK Fortranリニアコンピューティングライブラリのドキュメントに記載されており、それ以降、そのバリエーションは、たとえばTOP500スーパーコンピューターのランク付けに使用されています。



実装



かなり単純なタスクにもかかわらず、クロスプラットフォーム開発のガイドラインに従って実装することにしました。



最初のステップでは、クロスプラットフォームソリューションを構築します。



次に、MVPデザインパターンに従って、プレゼンターとビューを作成します

画像

テストを作成し、テストを通じてPresenterを実装します。 これには、NUnitとNSubstituteを使用します。 NUnitの説明には特別な意味はありません。私の意見では、これ以上便利なテストフレームワークはありません。 NSubstituteは、インターフェイスに基づいてスタブを作成するための非常に便利なフレームワークです。 フレームワークはNuGetを介してインストールされます。

ドックからNSubstituteを使用する小さな例
// Let's say we have a basic calculator interface: public interface ICalculator { int Add(int a, int b); string Mode { get; set; } event Action PoweringUp; } // We can ask NSubstitute to create a substitute instance for this type. We could ask for a stub, mock, fake, spy, test double etc., but why bother when we just want to substitute an instance we have some control over? _calculator = Substitute.For<ICalculator>(); // Now we can tell our substitute to return a value for a call: _calculator.Add(1, 2).Returns(3); Assert.That(_calculator.Add(1, 2), Is.EqualTo(3)); // We can check that our substitute received a call, and did not receive others: _calculator.Add(1, 2); _calculator.Received().Add(1, 2); _calculator.DidNotReceive().Add(5, 7); // If our Received() assertion fails, NSubstitute tries to give us some help as to what the problem might be: NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching: Add(1, 2) Actually received no matching calls. Received 2 non-matching calls (non-matching arguments indicated with '*' characters): Add(1, *5*) Add(*4*, *7*) // We can also work with properties using the Returns syntax we use for methods, or just stick with plain old property setters (for read/write properties): _calculator.Mode.Returns("DEC"); Assert.That(_calculator.Mode, Is.EqualTo("DEC")); _calculator.Mode = "HEX"; Assert.That(_calculator.Mode, Is.EqualTo("HEX"));
      
      







この場合、最初にSetupメソッドを作成します

 [TestFixtureSetUp] public void Setup() { view = Substitute.For<ILinpackView>(); presenter = new LinpackPresenter(view); }
      
      





そして、自然に非同期で簡単なテストを実行します

  [Test] public void CalculateAsyncTest() { presenter.CalculateAsync().Wait(); Assert.That(view.Mflops, Is.EqualTo(130.0).Within(5).Percent); }
      
      





サードパーティソフトウェアを使用すると、PCのパフォーマンスが約130 MFLOPS / sであることがわかりました。そのため、期待値に書き込み、エラーを追加します。



メソッド内で、非同期タスクを作成し、ビューに入力します。 すべてがシンプルで明確です。

 public Task CalculateAsync() { Linpack l = new Linpack(); return Task.Factory.StartNew(() => l.RunBenchmark()) .ContinueWith(t => { _view.Mflops = l.MFlops; _view.NormRes = l.ResIDN; _view.Precision = l.Eps; _view.Time = l.Time.ToString(); } ); }
      
      







プログラムは実際に実装されているため、プラットフォーム固有のコードはこれまでに作成されていません。 次に、Androidプロジェクトを作成します。



Visual Studio内のビジュアルデザイナーにより、必要なアプリケーションをすばやく簡単に挿入して、さまざまなテーマでどのように見えるかを確認できます。 ただし、アクティビティに適用されたトピックはないため、デバイスではデフォルトのビューが表示されます



リリースをコンパイルし、スタジオに適用されたウィザードで署名し、コンソールユーティリティadb.exeを使用してデバイスにインストールするだけです。





最近、コードの実行速度がデバッグ/リリースだけでなく、USBを介したデバイスの接続にも依存していることに気付きました。 これは、電話が開発モードで接続されている場合、Androidが大量のデバッグ情報をコンピューターに送信するために発生します。これは、特にTraceのようなロギング構造がある場合、操作の速度に影響する(または影響しない)可能性があります。 したがって、デバイスをオフにしてテストを実行します。



できた!



結果



2つのテストデバイス、HTC Desire with Android 2.3(Qualcomm QSD8250、1000 MHz、512 RAM)とFly IQ443 with Android 4.0.4(MediaTek MT6577、1000 MHz、512 RAM)



結果は次のとおりです。

HTCの欲求:





フライIQ443:





そして美しいグラフィックス





おわりに



テスト結果では、AndroidのMonoは少なくとも匹敵し、場合によってはDalvikよりも優れていることが示されています、一般的にはほぼ同等です。 次の列は間違っています。 Monoは独立してテストを2つのコアに並列化しましたが、タスクレベルのどこかで、AndroidのLinpackの場合は明示的にマルチスレッドテストを選択する必要があります。



ちなみに、このプロジェクトはリリースビルドのサイズの違いを示しています。 テストのJavaバージョンの重量はわずか280KBですが、Monodroidバージョンの重量はプロセッサタイプ(armeabiおよびarmeabi-v7)ごとに約2.3 MBです。 合計4.6 MBですが、これは現代のネットワークの状況では特に重要ではないようです。 このapkサイズが許容できない場合は、armeabiとarmeabi-v7のパッケージを個別にコンパイルして配布できます。GooglePlay ではプラットフォームごとに異なるapk ダウンロードできるためです。



アプリケーションのソースコードはこちらです。



PSデバイスの統計を収集したいと思います。 だから誰かがAndroidを持ち、10分間の空き時間があれば、 LINPACK for Androidと新しく作成されたMonoLINPACKを使用してデバイスのパフォーマンスを測定し、 ここに結果を書いていただければ非常に感謝します



PPS iOSの同様のテストは



UPD1現在のテストによると、MonoとTaskがデフォルトで4コアプロセッサ上のすべてのコアを使用するわけではないことは明らかです。 したがって、このようなデバイスでのLinpack for AndroidとMonoLinpackの結果は非常に異なります。 MonoLINPACKは、近い将来TPLを使用して変更されます。



All Articles