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では非常にうまくいきます。
グレッグ