Xamarin C#とJavaで記述されたAndroidアプリのパフォーマンスを比較するベンチマーク(コードと結果)を持っている人はいますか?[閉まっている]


544

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

他のデバイスやエミュレーターで私のテストを繰り返したい場合は、結果も知りたいです。

テストの結果

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

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

Java:合計時間(5実行):12361ミリ秒、ファイル読み取り合計:13304ミリ秒

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

Samsung Galaxy S2 SGH-I777(Android 4.0.4、API 15)-CyanogenMod ROM

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

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

Samsung GT-N7100(Android 4.1.1 JellyBean、API 16)-Samsung ROM

Java:合計時間(5回の実行):9742ミリ秒、ファイル読み取り合計:10111ミリ秒

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

エミュレータ-インテル(Android 4.2、API 17)

Java:合計時間(5実行):2699ミリ秒、ファイル読み取り合計:3127ミリ秒

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

エミュレータ-インテル(Android 2.3.7、API 10)

Java:合計時間(5実行):2992ミリ秒、ファイル読み取り合計:3591ミリ秒

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

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

Java:合計時間(5実行):41751ミリ秒、ファイル読み取り合計:43866ミリ秒

C#:合計時間(5回の実行):44136ミリ秒、ファイル読み取り合計:45109ミリ秒

簡単な議論

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

Intelエミュレーター(Intel HAXテクノロジーを使用すると、エミュレーターは高速仮想モードで実行されます)では、Xamarin C#コードはサンプルコードをJavaよりもはるかに高速に実行します(約1.35倍高速)。たぶん、モノの仮想マシンコードとライブラリは、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ミリ秒、ファイル読み取り合計:2248ミリ秒

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回の実行):7951ミリ秒、ファイル読み取り合計:8161ミリ秒

うわー!C#はJavaより優れていますか?私のGalaxy Note 2でテストを繰り返すことにしました:

Samsung Galaxy Note 2-ARM(Android 4.1.1)

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

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

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

Samsung Galaxy Note 2-ARM(Android 4.1.1)、省電力が無効

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

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

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

2013年7月12日を編集

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

Java:合計時間(5回の実行):3292ミリ秒、ファイル読み取り合計:3454ミリ秒

ネイティブサム:総計時間(5実行):537ミリ秒、ファイル読み取り合計:657ミリ秒

ネイティブアーム:合計時間(5実行):458ミリ秒、ファイル読み取り合計:587ミリ秒

私の特定のテストのように見えますが、ネイティブコードはJavaの6〜7倍高速です。警告:Androidではstd :: regexクラスを使用できなかったため、段落区切りまたはhtmlタグを検索する独自のルーチンを作成する必要がありました。正規表現を使用してPCで同じコードを最初にテストしたところ、Javaの約4〜5倍高速でした。

ふew!char *またはwchar *ポインタで生のメモリを再び目覚めさせたとき、私はすぐに20歳若くなったと感じました!:)

2013年7月15日を編集

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

いくつかの問題を抱えて、C#テストをAndroidのもう1つのC#プラットフォームであるDot42(バージョン1.0.1.71ベータ)に移植できました。暫定的な結果は、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とネイティブに連携し、C#からXamarinのようなJavaへの高価な相互運用を必要としません。

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

HTC Nexus One Android 2.3.7(ARM)

Java:合計時間(5実行):12187ミリ秒、ファイル読み取り合計:13200ミリ秒

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

Dot42 C#:総計時間(5実行):26000ミリ秒、ファイル読み取り合計:27168ミリ秒

Samsung Galaxy Note 2、Android 4.1.1(ARM)

Java:総計時間(5実行):6895ミリ秒、ファイル読み取り合計:7275ミリ秒

Xamarin C#:総計時間(5実行):6466ミリ秒、ファイル読み取り合計:6720ミリ秒

Dot42 C#:総計時間(5実行):11185ミリ秒、ファイル読み取り合計:11843ミリ秒

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デバイスからの結果を確認することは特に興味深いでしょう。

2013年7月26日更新

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

2013年7月30日更新-dot42のより良い結果

私のJavaコードのC#への(dot42メーカーからの)Robertの移植でDot42を再テストしました。Xamarin用に最初に行われたC#の移植で、ListArrayなどのいくつかのネイティブJavaクラスをC#にネイティブなListクラスなどに置き換えました。このような場所はDot42にメリットがあります。これは、JavaのようなDalvik VMで実行され、XamarinのようなMonoでは実行されないためです。Dot42の結果が大幅に改善されました。これが私のテストのログです:

2013年7月30日-Dot42 C#でJavaクラスを追加したDot42テスト

Intelエミュレータ、Android 4.2

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

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

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

Xamarin:
総計時間(5実行):1373ミリ秒、ファイル読み取り合計:1505ミリ秒

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

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

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

Dot42、String.Replace()を使用したGregのコード(JavaおよびRobertのコードと同様):
総計時間(5回の実行):9710ミリ秒、ファイル読み取り合計:10097ミリ秒

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

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

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

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

グレッグ


5
文字列とxamarin alpha 9にいくつかの最適化を施したNexus 7 4.2.2のデバッグモード:合計時間:3907 ms、ファイル読み取り合計:4016。「5回実行」とはどういう意味ですか?
Softlion 2013

1
「この質問は、討論、議論、投票、または拡張ディスカッションを求める可能性があります」<-上記を参照;)
LearnCocos2D 2013年

2
@ LearnCocos2D-具体的な結果と数値、つまり事実のみを報告しています。紳士は事実に異議を唱えない:)
gregko 2013年

2
まあ、科学者はそうします;)観察された行動と事実の間には違いがあります。事実になるにはまだまだ多くのことがあり、それでも他のユーザー/状況への適用性には疑問が残ります。これはベンチマークの核心であり、表面的な事実を提示するだけです。ベンダーxが特定のベンチマークアプリ用にドライバーを最適化したことがわかるまでは。関連するメモでは、テスターのバイアスを考慮して除外した後に反証された水に記憶(すなわちホメオパシーテスト)があることが一度証明され、その後統計的有意性を示すことができませんでした。
LearnCocos2D 2013年

3
さらに、次の+0.1バージョンのバンプにより、これらのパフォーマンス特性が大幅に変化する可能性があります。このとき、ここで提示するすべての優れた取り組みが「事実」から「気分」に変化します。しかし、ここに来る人は誰でもこれを事実として認識し、間違った結論を出すかもしれません。ベンチマークのもう一つの核心:それらは、特定の瞬間と使用されているソフトウェアのバージョンを代表するだけです。翌日、彼らはもはや現実を反映しないかもしれません。結果を再テストし続ける必要があります。これが、ここでの結果が主観的であり、ほとんどまたはまったく意味がないと見なされる理由です。
LearnCocos2D 2013年

回答:


62

ええ、XamarinのMono仮想マシンは、Androidで使用されているGoogleのDalvikよりも印象的です。私はHTC FlyerとAcer Iconia Tabタブレットでテストし、AndroidのC#ポートをMonoからJava Dalvikに対してベンチマークしました。AndroidのC#実装がうまく機能し、JavaベースのDalvikを真に売り出しました。


4
@PeterLawrey、私の質問の更新をご覧ください。私は実際のJavaコードの一部をC#に移植してベンチマークを実行し、それらをここに投稿するつもりです-彼らが私の質問を再開した場合、つまり、SO自警団がほぼ即座に閉じたためです。
gregko 2013年

1
@PeterLawrey-私は今テストを実施し、結果をStackOverflowに投稿しましたが、それでも「ロック」されたままで回答を投稿できないため、質問自体の内部にあります。可能であれば、投票を追加して質問を再度開いてください。その結果は興味深いものです。ARMJavaはハンズダウンで勝ち、IntelはMonoのC#コードがはるかに高速です。
gregko 2013年

9
@gregko C#が高速にエミュレートされていることは注目に値しますが、実際の電話ではJavaの方が高速です。私にとってこれは重要な違いです。エミュレータのパフォーマンスについて心配する必要はありません。実際には、エミュレータを本物と同じくらい低速/高速にすることをお勧めします。再開に投票しました。
Peter Lawrey 2013年

14
パフォーマンスのテストとして正規表現を使用するときは注意してください。REの実装におけるアルゴリズムの違いにより、大きな違いが生じる可能性があります。上記でテストしているのはREの実装品質であり、DalvikまたはMono VMではありません。より良いテストは、各言語に慣用的なスタイルで書かれた同一の明白なアルゴリズムを使用する手書きの解析コードです。
クリストファー

4
この答えは、これらのテストまたはテスト結果をどのように実行したかについての説明がなければ意味がありません。現状のまま:完全に意見に基づいています。
ロルフ・ツ


34

最近、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への文字列のマーシャリングが、XamarinでのネイティブのC#よりもAndroidでの方が速いことです。


1
これはまた、「バインディング」により、Xamerinがシステムと対話する必要があるためと考えられます。デフォルトでは、すべてのシステムコールがJavaクラスに渡されますが、時間がかかるMono VMに委任される必要があります。同じことが逆にも起こります。私はこれを私の回答でもう少し説明しました:stackoverflow.com/a/46973819/1052697
Rolfツオクト

33

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

簡単に言えば、Xamarinはネイティブコードよりもパフォーマンスが優れている場合があります。アプリのサイズ、読み込み時間、Azureサービスからのリストの読み込み、素数計算をテストしました。

楽しい!

編集:私はデッドリンクを更新し、パート2があることに気付きました


11

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

Samsung Galaxy A7:Android OSバージョン:6.0中央処理装置:Octa-core 1.9 GHz Cortex-A53 RAM:3GBディスプレイ解像度:1920×1080

iPhone 6s:iOSバージョン:10.3.3中央処理装置:デュアルコア1.84 GHzツイスターRAM:2 GBディスプレイ解像度:1334×750

いくつかの一般的な機能を比較し、それぞれに独自のアプリケーションがあります。

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

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


こんにちは世界

基本的なHellow Worldパフォーマンスの比較


Rest API

OpenWeatherMap APIを使用して、アプリがREST APIを介してリクエストを送信し、さらにデータを処理することなくレスポンスを受信するのにかかる時間を測定することを目的とした一連のテスト。

Rest APIのパフォーマンス比較


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

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

ファーストラン :

JSONシリアル化の初回実行

JSON逆シリアル化の初回実行

(ネイティブiOS JSON操作はこのテストを中断していますが、Xamarinが2番目に追加します)

JSONシリアル化の2回目の実行

JSON逆シリアル化2回目の実行


写真の操作

最初に、3つの異なる解像度の画像を読み込みます。

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

Image First Load Android

画像の最初の読み込み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パフォーマンス

SQLite iOSパフォーマンス


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/

私の答えを強化するために説明してくれてありがとう、これが少し役立つことを願っています:)


7

パフォーマンス

パフォーマンスは、パフォーマンスの意味を定義しない場合、あいまいな言葉です。単純な計算パフォーマンスの場合、Xamarinは、計算の性質によってはJavaよりも高速になる場合があります。

Androidには、コードを実行するためのmultipeフォームが付属しています。

  • RenderScript(CPUおよびGPU)
  • Java(SDK)
  • C ++(NDK)
  • OpenGL(GPU)

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

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

Xamarinとそれが遅くなる理由

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

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

知っておくべき重要なバインディングにはいくつかの種類があります。

  • JNI(Java Native Interface): Javaコード(SDK)とネイティブC ++コード(NDK)の間のインターフェースとして多くのAndroidアプリケーションで使用されるバインディング。
  • MCW(マネージコール可能ラッパー):マネージC#コードからJavaコード(Androidランタイム)へのインターフェイスとしてXamarinで利用できるバインディング。
  • ACW(Android Callable Wrappers): 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呼び出しにかかるJava操作の数を計算しました。JNI呼び出しを行うことの定量的なオーバーヘッドはどれくらいですか?

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

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

バインディングの他にも、バイナリのサイズ、メモリへのアプリのロード、I / Oオペレーションなど、実際のパフォーマンスを説明する際には、他にも多くの要因が関係しています。これらの事柄のいくつかを調査するブログ投稿は、こちらにあります:https : //magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.