私はXamarinの主張に遭遇しました。AndroidでのMonoの実装とC#でコンパイルされたアプリはJavaコードより速いということです。そのような主張を検証するために、異なるAndroidプラットフォーム上で非常によく似たJavaコードとC#コードで実際のベンチマークを実行した人はいましたか?
答えがないし、他の人によって行われたそのようなベンチマークを見つけることができなかったので、私自身のテストをすることにしました。残念ながら、私の質問は「ロック」されたままなので、これを回答として投稿することはできません。質問を編集するだけです。この質問をもう一度開くために投票してください。 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"ビルドのみをテストしました。
Java:総合計時間(5回):12361 ms、ファイル読み取りの合計:13304 ms
C#:総合計時間(5回):17504ミリ秒、ファイル読み取りの合計:17956ミリ秒
Java:総合計時間(5回):8947ミリ秒、ファイル読み取りの合計:9186ミリ秒
C#:総合計時間(5回):9884ミリ秒、ファイル読み取りの合計:10247ミリ秒
Java:総合計時間(5回):9742 ms、ファイル読み取りの合計:10111 ms
C#:総合計時間(5回):10459ミリ秒、ファイル読み取りの合計:10696ミリ秒
Java:総合計時間(5回):2699 ms、ファイル読み取りの合計:3127 ms
C#:総合計時間(5回):2049ミリ秒、ファイル読み取りの合計:2182ミリ秒
Java:総合計時間(5回):2992 ms、ファイル読み取りの合計:3591 ms
C#:総合計時間(5回):2049ミリ秒、ファイル読み取りの合計:2257ミリ秒
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の方がはるかに最適化されているでしょうか。
Oracle VirtualBoxで動作するGenymotion Androidエミュレータをインストールしたところです。これもARMプロセッサをエミュレートするのではなく、ネイティブのIntelプロセッサを使用しています。 Intel HAXエミュレータと同様に、ここでもC#がはるかに高速に実行されます。これが私の結果です。
Java:総合計時間(5回):2069 ms、ファイル読み取りの合計:2248 ms
C#:総合計時間(5回):1543ミリ秒、ファイル読み取りの合計:1642ミリ秒
私はそれからXamarin.Androidベータ版、バージョン4.7.11へのアップデートがあったことに気づきました、そしてリリースノートは同様にMonoランタイムにおけるいくつかの変更を述べました。いくつかのARMデバイスをすばやくテストすることにしましたが、大きな驚き - C#の数値が改善されました。
Java:総合計時間(5回):8103 ms、ファイル読み取りの合計:8569 ms
C#:総合計時間(5回):7951ms、ファイル読み取りの合計:8161ms
うわー! C#は今Javaよりも優れている?私のギャラクシーノート2でテストを繰り返すことにしました:
Java:総合計時間(5回):9675 ms、ファイル読み取りの合計:10028 ms
C#:総合計時間(5回):9911ミリ秒、ファイル読み取り合計:10104ミリ秒
ここでC#は少し遅くなるように見えますが、これらの数字は私に一時停止を与えました:なぜ注2がより速いプロセッサを持っていても、時間がNook HD +より長いのはなぜですか?答え:省電力モード。 Nookでは無効、注2では有効でした。省電力モードを無効にしてテストすることを決定しました(有効と同様に、プロセッサ速度も制限されます)。
Java:総合計時間(5回):7153 ms、ファイル読み取りの合計:7459 ms
C#:総合計時間(5回):6906ミリ秒、ファイル読み取り合計:7070ミリ秒
さて、驚くべきことに、C#はARMプロセッサ上のJavaよりもわずかに速いです。大きな改善!
私たちは皆、スピードの面でネイティブコードに勝るものは何もないことを知っています。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月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倍遅いだけです。これが私の結果です。
Java:総合計時間(5回):12187 ms、ファイル読み取りの合計:13200 ms
Xamarin C#:総合計時間(5回):13935 ms、ファイル読み取りの合計:14465 ms
Dot42 C#:総合計時間(5回):26000 ms、ファイル読み取りの合計:27168 ms
Java:総合計時間(5回):6895 ms、ファイル読み取りの合計:7275 ms
Xamarin C#:総合計時間(5回):6466 ms、ファイル読み取りの合計:6720 ms
Dot42 C#:総合計時間(5回):11185 ms、ファイル読み取りの合計:11843 ms
Java:総合計時間(5回):2389ミリ秒、ファイル読み取りの合計:2770ミリ秒
Xamarin C#:総合計時間(5回):1748ミリ秒、ファイル読み取りの合計:1933ミリ秒
Dot42 C#:総合計時間(5回):5150ミリ秒、ファイル読み取りの合計:5459ミリ秒
私にとっては、Xamarin C#が新しいARMデバイスではJavaよりやや速く、古いNexus Oneでやや遅いことに注意することも興味深いことでした。誰もがこれらのテストを実行したい場合は、私に知らせてください。GitHubのソースを更新します。 Intelプロセッサを搭載した実際のAndroidデバイスからの結果を見ることは特に興味深いでしょう。
ベンチマークアプリによって最新のXamarin.Android 4.8、および本日リリースされたdot42 1.0.1.72アップデートで再コンパイルされた簡単なアップデート - 以前に報告された結果からの重要な変更はありません。
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 msDot42、GregのコードでString.Replace()を使用する(JavaおよびRobertのコードと同様)。
総合計時間(5回):3027ミリ秒、ファイル読み取り合計:3206ミリ秒Dot42、Robertのコード:
総合計時間(5回):1781ミリ秒、ファイル読み取りの合計:1999ミリ秒ザマリン:
総合計時間(5回):1373 ms、ファイル読み取りの合計:1505 msJava:
総合計時間(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 msDot42、Robertのコード:
総合計時間(5回):6279ミリ秒、ファイル読み取り合計:6622ミリ秒ザマリン:
総合計時間(5回):6201ミリ秒、ファイル読み取りの合計:6476ミリ秒Java:
総合計時間(5回):7141ミリ秒、ファイル読み取りの合計:7479ミリ秒
私はまだDot42にはまだ長い道のりがあると思います。 Javaのようなクラス(例えばArrayList)とそれを使った優れたパフォーマンスがあると、コードをJavaからC#に移植するのが少し簡単になります。しかし、これは私があまりしそうにないことです。ネイティブのC#クラス(Listなど)を使用する既存のC#コード(ライブラリなど)を使用したいのですが、現在のdot42コードでは遅くなり、Xamarinでは非常にうまく機能します。
グレッグ
ええ、XamarinのMono仮想マシンは、AndroidのGoogleのDalvikよりも印象的です。私はHTC FlyerとAcer Iconia Tabタブレットでそれをテストして、AndroidのC#実装をうまく、そしてJavaベースのDalvikを本当に動かしながら、Monoを通してAndroidのC#ポートをベンチマークしました。
I came across this interesting post
https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz
この情報がお役に立てば幸いです。
これは私があなたと共有したいもう一つのより更新されたブログ記事です 。彼は、IOとAndroidの両方で、XamarinとネイティブコードおよびCordovaを比較します。
一言で言えば、Xamarinはネイティブコードよりもパフォーマンスが良い場合があります。彼はアプリのサイズ、ロード時間、Azureサービスからのリストのロード、および素数計算をテストしました。
楽しい!
編集:私はデッドリンクを更新し、私はそれに気づいた パート2があります
私たちは最近、アプリに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よりも速いことです。
以下は、ネイティブ、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
各テストは数回繰り返され、グラフは平均結果を示します。
ハローワールド
Rest API
OpenWeatherMap APIを使用して、REST APIを介してアプリが要求を送信し、それ以上のデータ処理を行わずに応答を受信するのにかかる時間を測定することを目的とした一連のテスト。
JSON操作Newtonsoft Json.netフレームワークを使用して、すべてのXamarinアプリケーションでJSONオブジェクトをシリアル化および逆シリアル化するためのテスト。 JacksonのネイティブライブラリとGSONの2つのJavaライブラリを使用して、ネイティブAndroidのシリアル化と逆シリアル化をテストしました。
1回は最初から、もう1回はキャッシュされた情報と操作を含む2つの実行が行われます。
ファーストラン :
(ネイティブiOSのJSON Operationsがこのテストを2回失敗し、Xamarinが2回目に参加しました)
フォト操作
まず3つの異なる解像度の画像を読み込みます。
Resolution – 858×569, Size – 868Kb
Resolution – 2575×1709, Size – 8Mb
Resolution – 4291×2848, Size – 28.9Mb
このテストのXamarin.Formsの結果について不明な点があるため、グラフには含まれていません。
SQLiteオペレーション
テストされた2つの操作
BulkInsert: Loading rows of data into a database table.
GetAll: Retrieving all data from the database.
10,000レコードを持つデータベースを使って。すべての操作はデバイス上で内部的に処理されました。
Xamarin Native(Xamarin.iOS/Xamarin.Android)は、ネイティブコードに代わる優れた選択肢として自分自身を示していますが、Xamarin.Formsは多くの場合遅いと思われますが、本当にシンプルなアプリケーションを迅速に開発するための本当に良い解決策になります。
完全なテストはこのソースから来ます:
私の答えをより良くするための説明を私に与えてくれてありがとう、これが少し助けになることを願います:)
あなたがあなたがパフォーマンスによってあなたが意味するものを定義しないならば、パフォーマンスは曖昧な言葉です、それが明白な計算パフォーマンスであるならば、Xamarinは計算の性質によってはJavaより速いかもしれません。
Androidには、コードを実行するためのマルチフォームがネイティブに付属しています。
コードをネイティブに実行すればするほど、ソリューションが速くなることは明らかです。ランタイムベースの言語は、CPU上で直接実行される言語に勝ることは決してありません。
しかし一方で、実際の使用パフォーマンスを測定したいのであれば、JavaはXamarinよりも速いでしょう。
Xamarinを普通のJavaアプリケーションと比較すると、Xamarinのパフォーマンスは遅くなる可能性があるため、非常に高速になる可能性があります。
実際の例では、多くのAndroid/Java(システム)呼び出しは、いわゆるバインディングを使用してXamarinランタイムとの間で委任する必要があるため、XamarinアプリケーションはJavaアプリケーションより遅くなる可能性が非常に高いです。
知っておくことが重要ないくつかの異なるタイプのバインディングがあります。
バインディングはパフォーマンスの面で非常にコストがかかります。 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
これはかなり古いテストですが、関連性がある可能性があります。 https://github.com/EgorBo/Xamarin.Android-vs-Java
算数テスト
コレクション、総称、カスタム値型
文字列の取り扱い
UPD:Google Pixel 2の新しいデータ(ありがとう yousha-aleayoub )