web-dev-qa-db-ja.com

Xamarin C#とJavaで書かれたAndroidアプリのパフォーマンスを比較するベンチマーク(コードと結果)がありますか?

私はXamarinの主張に遭遇しました。AndroidでのMonoの実装とC#でコンパイルされたアプリはJavaコードより速いということです。そのような主張を検証するために、異なるAndroidプラットフォーム上で非常によく似たJavaコードとC#コードで実際のベンチマークを実行した人はいましたか?

2013年6月18日追加

答えがないし、他の人によって行われたそのようなベンチマークを見つけることができなかったので、私自身のテストをすることにしました。残念ながら、私の質問は「ロック」されたままなので、これを回答として投稿することはできません。質問を編集するだけです。この質問をもう一度開くために投票してください。 C#にはXamarin.Android Ver。を使いました。 4.7.09001β。ソースコード、私がテストとコンパイルしたAPKパッケージに使用したデータはすべてGitHubにあります。

Java: https://github.com/gregko/TtsSetup_Java

C#: https://github.com/gregko/TtsSetup_C_sharp

他のデバイスやエミュレータで私のテストを繰り返したいという人がいるなら、私もその結果を学ぶことに興味があります。

私のテストの結果

私は自分のセンテンスエクストラクタクラスを(私の@Voice Aloud Readerアプリから)C#に移植し、英語、ロシア語、フランス語、ポーランド語、チェコ語の10のHTMLファイルでいくつかのテストを実行しました。各実行は10個すべてのファイルに対して5回実行され、3つの異なるデバイスと1つのエミュレータの合計時間が以下に掲載されています。デバッグを有効にせずに "Release"ビルドのみをテストしました。

HTC Nexus One Android 2.3.7(API 10) - CyanogenMod ROM

Java:総合計時間(5回):12361 ms、ファイル読み取りの合計:13304 ms

C#:総合計時間(5回):17504ミリ秒、ファイル読み取りの合計:17956ミリ秒

サムスンギャラクシーS2 SGH - I777(アンドロイド4.0.4、API 15) - CyanogenMod ROM

Java:総合計時間(5回):8947ミリ秒、ファイル読み取りの合計:9186ミリ秒

C#:総合計時間(5回):9884ミリ秒、ファイル読み取りの合計:10247ミリ秒

サムスンGT-N7100(アンドロイド4.1.1ジェリービーン、API 16) - サムスンROM

Java:総合計時間(5回):9742 ms、ファイル読み取りの合計:10111 ms

C#:総合計時間(5回):10459ミリ秒、ファイル読み取りの合計:10696ミリ秒

エミュレータ - Intel(Android 4.2、API 17)

Java:総合計時間(5回):2699 ms、ファイル読み取りの合計:3127 ms

C#:総合計時間(5回):2049ミリ秒、ファイル読み取りの合計:2182ミリ秒

エミュレータ - Intel(Android 2.3.7、API 10)

Java:総合計時間(5回):2992 ms、ファイル読み取りの合計:3591 ms

C#:総合計時間(5回):2049ミリ秒、ファイル読み取りの合計:2257ミリ秒

エミュレータ - アーム(Android 4.0.4、API 15)

Java:総合計時間(5回):41751 ms、ファイル読み取りの合計:43866 ms

C#:総合計時間(5回):44136 ms、ファイル読み取りの合計:45109 ms

簡単な議論

私のテストコードは主にテキスト解析、置換および正規表現検索を含んでいます、おそらく他のコード(例えば、より多くの数値演算)のために結果は異なるでしょう。 ARMプロセッサを搭載したすべてのデバイスで、JavaはXamarin C#コードよりもパフォーマンスが優れていました。最大の違いはAndroid 2.3の下で、そこではC#のコードが実行されます。 Java速度の70%.

Intelエミュレータ(Intel HAXテクノロジを使用すると、エミュレータは高速virtモードで実行されます)では、Xamarin C#コードは私のサンプルコードをJavaよりもはるかに速く(約1.35倍速く)実行します。たぶん、Mono仮想マシンコードとライブラリは、ARMよりもIntelの方がはるかに最適化されているでしょうか。

2013年7月8日編集

Oracle VirtualBoxで動作するGenymotion Androidエミュレータをインストールしたところです。これもARMプロセッサをエミュレートするのではなく、ネイティブのIntelプロセッサを使用しています。 Intel HAXエミュレータと同様に、ここでもC#がはるかに高速に実行されます。これが私の結果です。

Genymotionエミュレータ - Intel(Android 4.1.1、API 16)

Java:総合計時間(5回):2069 ms、ファイル読み取りの合計:2248 ms

C#:総合計時間(5回):1543ミリ秒、ファイル読み取りの合計:1642ミリ秒

私はそれからXamarin.Androidベータ版、バージョン4.7.11へのアップデートがあったことに気づきました、そしてリリースノートは同様にMonoランタイムにおけるいくつかの変更を述べました。いくつかのARMデバイスをすばやくテストすることにしましたが、大きな驚き - C#の数値が改善されました。

BN Nook XD +、ARM(Android 4.0)

Java:総合計時間(5回):8103 ms、ファイル読み取りの合計:8569 ms

C#:総合計時間(5回):7951ms、ファイル読み取りの合計:8161ms

うわー! C#は今Javaよりも優れている?私のギャラクシーノート2でテストを繰り返すことにしました:

サムスンギャラクシーノート2 - ARM(Android 4.1.1)

Java:総合計時間(5回):9675 ms、ファイル読み取りの合計:10028 ms

C#:総合計時間(5回):9911ミリ秒、ファイル読み取り合計:10104ミリ秒

ここでC#は少し遅くなるように見えますが、これらの数字は私に一時停止を与えました:なぜ注2がより速いプロセッサを持っていても、時間がNook HD +より長いのはなぜですか?答え:省電力モード。 Nookでは無効、注2では有効でした。省電力モードを無効にしてテストすることを決定しました(有効と同様に、プロセッサ速度も制限されます)。

サムスンギャラクシーノート2 - ARM(Android 4.1.1)、省電力無効

Java:総合計時間(5回):7153 ms、ファイル読み取りの合計:7459 ms

C#:総合計時間(5回):6906ミリ秒、ファイル読み取り合計:7070ミリ秒

さて、驚くべきことに、C#はARMプロセッサ上のJavaよりもわずかに速いです。大きな改善!

2013年7月12日編集

私たちは皆、スピードの面でネイティブコードに勝るものは何もないことを知っています。JavaまたはC#でのセンテンススプリッタのパフォーマンスには満足していませんでした。 C++で書き直すことにしました。これは、省電力モードを無効にした場合の、Galaxy Note 2でのネイティブ速度とJava速度の比較です(その他の理由で、以前のテストよりも小さいファイルのセットです)。

Java:総合計時間(5回):3292 ms、ファイル読み取りの合計:3454 ms

親指:総合計時間(5回):537 ms、ファイル読み取りの合計:657 ms

ネイティブアーム:総合計時間(5回):458 ms、ファイル読み取りの合計:587 ms

私の特定のテストでは、ネイティブコードはJavaより6〜7倍高速です。注意:Androidではstd :: regexクラスを使用できなかったので、段落の切れ目やhtmlタグを検索する専用のルーチンを作成しなければなりませんでした。正規表現を使用して、PC上で同じコードを最初にテストしたところ、Javaよりも約4〜5倍高速でした。

あー! char *またはwchar *ポインタを使用して生のメモリを再度目覚めさせたところ、私は即座に20歳若いと感じました! :)

2013年7月15日編集

(2013年7月30日の編集、Dot42でのより良い結果については以下をご覧ください)

多少の困難はありましたが、私は自分のC#テストをAndroid用の別のC#プラットフォームであるDot42(バージョン1.0.1.71 beta)に移植することに成功しました。暫定的な結果は、Intel Androidエミュレータ上で、Dot42コードがXamarin C#(v。4.7.11)よりも約3倍(3倍)遅いことを示しています。 1つの問題は、Dot42のSystem.Text.RegularExpressionsクラスにはXamarinテストで使用したSplit()関数がないため、代わりにJava.Util.RegexクラスとJava.Util.Regex.Pattern.Split()を使用したことです。したがって、コード内のこの特定の場所には、この小さな違いがあります。大きな問題ではないはずです。 Dot42はDalvik(DEX)コードにコンパイルされるため、Android上のJavaとネイティブに連携します。XamarinのようにC#からJavaへの高価な相互運用は必要ありません。

比較のために、ARMデバイスでもテストを実行しています - ここでのDot42コードはXamarin C#よりも2倍遅いだけです。これが私の結果です。

HTC Nexus One Android 2.3.7(ARM)

Java:総合計時間(5回):12187 ms、ファイル読み取りの合計:13200 ms

Xamarin C#:総合計時間(5回):13935 ms、ファイル読み取りの合計:14465 ms

Dot42 C#:総合計時間(5回):26000 ms、ファイル読み取りの合計:27168 ms

サムスンギャラクシーノート2、アンドロイド4.1.1(ARM)

Java:総合計時間(5回):6895 ms、ファイル読み取りの合計:7275 ms

Xamarin C#:総合計時間(5回):6466 ms、ファイル読み取りの合計:6720 ms

Dot42 C#:総合計時間(5回):11185 ms、ファイル読み取りの合計:11843 ms

Intelエミュレータ、Android 4.2(x86)

Java:総合計時間(5回):2389ミリ秒、ファイル読み取りの合計:2770ミリ秒

Xamarin C#:総合計時間(5回):1748ミリ秒、ファイル読み取りの合計:1933ミリ秒

Dot42 C#:総合計時間(5回):5150ミリ秒、ファイル読み取りの合計:5459ミリ秒

私にとっては、Xamarin C#が新しいARMデバイスではJavaよりやや速く、古いNexus Oneでやや遅いことに注意することも興味深いことでした。誰もがこれらのテストを実行したい場合は、私に知らせてください。GitHubのソースを更新します。 Intelプロセッサを搭載した実際のAndroidデバイスからの結果を見ることは特に興味深いでしょう。

更新7/26/2013

ベンチマークアプリによって最新のXamarin.Android 4.8、および本日リリースされたdot42 1.0.1.72アップデートで再コンパイルされた簡単なアップデート - 以前に報告された結果からの重要な変更はありません。

更新7/30/2013 - dot42のより良い結果

Robertの(dot42メーカーからの)移植した私のJavaコードのC#への移植でDot42を再テストした。 Xamarinに対して最初に行われた私のC#移植で、私はListArrayのようないくつかのネイティブJavaクラスをC#などのネイティブのListクラスに置き換えました。Robertは私のDot42ソースコードを持っていませんでした。 Dot42にメリットがあるこのような場所は、JavaのようにDalvik VMで動作し、XamarinのようにMonoでは動作しないためです。今すぐDot42結果がはるかに優れています。これが私のテストからのログです。

7/30/2013 - Dot42はDot42 Cでより多くのJavaクラスでテストする

Intelエミュレータ、Android 4.2

Dot42、StringBuilder.Replace()を使用したGregのコード(Xamarinの場合と同様)。
総合計時間(5回):3646 ms、ファイル読み取りの合計:3830 ms

Dot42、GregのコードでString.Replace()を使用する(JavaおよびRobertのコードと同様)。
総合計時間(5回):3027ミリ秒、ファイル読み取り合計:3206ミリ秒

Dot42、Robertのコード:
総合計時間(5回):1781ミリ秒、ファイル読み取りの合計:1999ミリ秒

ザマリン:
総合計時間(5回):1373 ms、ファイル読み取りの合計:1505 ms

Java:
総合計時間(5回):1841ミリ秒、ファイル読み取り合計:2044ミリ秒

ARM、Samsung Galaxy Note 2、省電力オフ、Android 4.1.1

Dot42、StringBuilder.Replace()を使用したGregのコード(Xamarinの場合と同様)。
総合計時間(5回):10875ミリ秒、ファイル読み取りの合計:11280ミリ秒

Dot42、GregのコードでString.Replace()を使用する(JavaおよびRobertのコードと同様)。
総合計時間(5回):9710 ms、ファイル読み取りの合計:10097 ms

Dot42、Robertのコード:
総合計時間(5回):6279ミリ秒、ファイル読み取り合計:6622ミリ秒

ザマリン:
総合計時間(5回):6201ミリ秒、ファイル読み取りの合計:6476ミリ秒

Java:
総合計時間(5回):7141ミリ秒、ファイル読み取りの合計:7479ミリ秒

私はまだDot42にはまだ長い道のりがあると思います。 Javaのようなクラス(例えばArrayList)とそれを使った優れたパフォーマンスがあると、コードをJavaからC#に移植するのが少し簡単になります。しかし、これは私があまりしそうにないことです。ネイティブのC#クラス(Listなど)を使用する既存のC#コード(ライブラリなど)を使用したいのですが、現在のdot42コードでは遅くなり、Xamarinでは非常にうまく機能します。

グレッグ

530
gregko

ええ、XamarinのMono仮想マシンは、AndroidのGoogleのDalvikよりも印象的です。私はHTC FlyerとAcer Iconia Tabタブレットでそれをテストして、AndroidのC#実装をうまく、そしてJavaベースのDalvikを本当に動かしながら、Monoを通してAndroidのC#ポートをベンチマークしました。

62
klvtsov
I came across this interesting post

https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz

Android App Performance

iOS App Performance

この情報がお役に立てば幸いです。

これは私があなたと共有したいもう一つのより更新されたブログ記事です 。彼は、IOとAndroidの両方で、XamarinとネイティブコードおよびCordovaを比較します。

一言で言えば、Xamarinはネイティブコードよりもパフォーマンスが良い場合があります。彼はアプリのサイズ、ロード時間、Azureサービスからのリストのロード、および素数計算をテストしました。

楽しい!

編集:私はデッドリンクを更新し、私はそれに気づいた パート2があります

34
Daniel

私たちは最近、アプリにXamarinを使って調査しました。私たちはWindows RTバージョンの我々のアプリのためにすでに書いたC#コードを利用しました。いくつかの具体的な詳細は、Androidのバージョン用に書き直す必要がありました。

私たちが発見したのは、Xamarin C#のI/OはJavaよりも約2倍遅いということです。私たちのアプリはI/Oに強く依存しています。原因はまだわかっていませんが、現時点ではマーシャリングによるものと想定しています。ほとんどの場合、Mono VM内に留まることを試みますが、Monoが実際にディスクにアクセスする方法はわかりません。

それはまた私達のC#コードがSQLite.NET( https://github.com/praeclarum/sqlite-net )を使用していることを伝えています。 SQLite.NETコードを使用した同一の取得も、AndroidのJava SQLiteラッパーを使用した場合より2倍遅くなります。ソースコードを見た後、それは直接Cの.dllにバインドするように見えるので、私はなぜそれがそんなに遅くなるのかわかりません。 1つの可能性は、ネイティブからJavaへの文字列のマーシャリングが、C#へのネイティブよりもAndroidの方がXamarinよりも速いことです。

33
Christopher

以下は、ネイティブ、Xamarin、およびXamarin.Formsソリューション(テストにはiOSパフォーマンスも含まれています)の間の別のテストで、以下の2つのデバイスで見つけたいくつかの情報です。

サムスンギャラクシーA7:Android OSのバージョン:6.0中央処理装置:オクタコア1.9 GHz Cortex-A53 RAM:3 GB表示解像度:1920×1080

iPhone 6s:iOS版:10.3.3中央処理装置:デュアルコア1.84 GHz Twister RAM:2 GBディスプレイ解像度:1334×750

いくつかの共通の機能について比較が行われ、それぞれに独自のアプリケーションがあります。

- Basic “Hello World”
- REST API
- JSON Serialization/Deserialization
- Photo Loading
- SQL Database Insert and Get All

各テストは数回繰り返され、グラフは平均結果を示します。


ハローワールド

Basic Hellow World performance comparison


Rest API

OpenWeatherMap APIを使用して、REST AP​​Iを介してアプリが要求を送信し、それ以上のデータ処理を行わずに応答を受信するのにかかる時間を測定することを目的とした一連のテスト。

Rest API performance comparison


JSON操作Newtonsoft Json.netフレームワークを使用して、すべてのXamarinアプリケーションでJSONオブジェクトをシリアル化および逆シリアル化するためのテスト。 JacksonのネイティブライブラリとGSONの2つのJavaライブラリを使用して、ネイティブAndroidのシリアル化と逆シリアル化をテストしました。

1回は最初から、もう1回はキャッシュされた情報と操作を含む2つの実行が行われます。

ファーストラン :

JSON serialization first run

JSON deserialization first run

(ネイティブiOSのJSON Operationsがこのテストを2回失敗し、Xamarinが2回目に参加しました)

JSON Serialization second run

JSON Deserialization second run


フォト操作

まず3つの異なる解像度の画像を読み込みます。

Resolution – 858×569, Size – 868Kb
Resolution – 2575×1709, Size – 8Mb
Resolution – 4291×2848, Size – 28.9Mb

Image First Load Android

Image First Load iOS

このテストのXamarin.Formsの結果について不明な点があるため、グラフには含まれていません。


SQLiteオペレーション

テストされた2つの操作

BulkInsert: Loading rows of data into a database table.
GetAll: Retrieving all data from the database.

10,000レコードを持つデータベースを使って。すべての操作はデバイス上で内部的に処理されました。

SQLite Android performances

SQLite iOS performances


Xamarin Native(Xamarin.iOS/Xamarin.Android)は、ネイティブコードに代わる優れた選択肢として自分自身を示していますが、Xamarin.Formsは多くの場合遅いと思われますが、本当にシンプルなアプリケーションを迅速に開発するための本当に良い解決策になります。

完全なテストはこのソースから来ます:

https://www.altexsoft.com/blog/engineering/performance-comparison-xamarin-forms-xamarin-ios-xamarin-Android-vs-Android-and-ios-native-applications/

私の答えをより良くするための説明を私に与えてくれてありがとう、これが少し助けになることを願います:)

10
Burgito

パフォーマンス

あなたがあなたがパフォーマンスによってあなたが意味するものを定義しないならば、パフォーマンスは曖昧な言葉です、それが明白な計算パフォーマンスであるならば、Xamarinは計算の性質によってはJavaより速いかもしれません。

Androidには、コードを実行するためのマルチフォームがネイティブに付属しています。

  • RenderScript(CPUとGPU)
  • Java(SDK)
  • C++(NDK)
  • OpenGL(GPU)

コードをネイティブに実行すればするほど、ソリューションが速くなることは明らかです。ランタイムベースの言語は、CPU上で直接実行される言語に勝ることは決してありません。

しかし一方で、実際の使用パフォーマンスを測定したいのであれば、JavaはXamarinよりも速いでしょう。

Xamarinとそれが遅くなる理由

Xamarinを普通のJavaアプリケーションと比較すると、Xamarinのパフォーマンスは遅くなる可能性があるため、非常に高速になる可能性があります。

実際の例では、多くのAndroid/Java(システム)呼び出しは、いわゆるバインディングを使用してXamarinランタイムとの間で委任する必要があるため、XamarinアプリケーションはJavaアプリケーションより遅くなる可能性が非常に高いです。

知っておくことが重要ないくつかの異なるタイプのバインディングがあります。

  • JNI(Java Native Interface):多くのAndroidアプリケーションでJavaコード(SDK)とネイティブC++コード(NDK)の間のインターフェースに使用されるバインディング。
  • MCW(Managed Callable Wrappers):マネージドC#コードからJavaコードにインターフェースするためにXamarinで利用可能なバインディング(Androidランタイム)。
  • ACW(Android呼び出し可能ラッパー):Javaコード(Androidランタイム)からマネージドC#コードへのインターフェースとしてXamarinで利用可能なバインディング。

MCWとACWの詳細はこちら: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform /

バインディングはパフォーマンスの面で非常にコストがかかります。 JavaからC++メソッドを呼び出すと、呼び出し時間に大きなオーバーヘッドが追加されます。C++内からC++メソッドを呼び出す方がはるかに何倍も高速です。

パフォーマンステストを行って、JNI呼び出しの平均コストがいくらであるかを計算するためのパフォーマンステストを行いました。 JNI呼び出しを行うことによる量的オーバーヘッドはいくらですか?

しかし、JNI呼び出しだけでなく、MCWおよびACWとの間の呼び出しもコストがかかります。現実世界のXamarinアプリケーションはバインディングを使用して多くの呼び出しを行います。この現実世界のためにXamarinアプリケーションの使用は普通の古いJavaアプリケーションよりも遅くなる可能性があります(そして一般に遅くなるでしょう)。しかし、Xamarinアプリケーションがどのように設計されているかによっては、ユーザーが違いに気付くことさえない可能性が非常に高いです。

TLDR /結論:Xamarinはalソートバインディングを使用する必要がありますが、これは時間がかかります。

バインディング以外にも、実世界のパフォーマンスについて話すときには、他にも多くの要因があります。たとえば、バイナリのサイズ、メモリへのアプリケーションのロード、I/O操作などです。これらのことのいくつかを調査するブログ投稿はここで見つけることができます: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms

6
Rolf ツ

これはかなり古いテストですが、関連性がある可能性があります。 https://github.com/EgorBo/Xamarin.Android-vs-Java

算数テスト

enter image description here

コレクション、総称、カスタム値型

enter image description here

文字列の取り扱い

enter image description here

UPD:Google Pixel 2の新しいデータ(ありがとう yousha-aleayoub

Pixel 2 tests

2
Denis Gordin