Saya menemukan Xamarin mengklaim bahwa implementasi Mono mereka di Android dan aplikasi yang dikompilasi C # lebih cepat daripada kode Java. Adakah yang melakukan tolok ukur aktual pada kode Java dan C # yang sangat mirip pada platform Android yang berbeda untuk memverifikasi klaim tersebut, dapat memposting kode dan hasil?
Ditambahkan 18 Juni 2013
Karena tidak ada jawaban dan tidak dapat menemukan benchmark yang dilakukan oleh orang lain, memutuskan untuk melakukan tes saya sendiri. Sayangnya, pertanyaan saya tetap "terkunci" sehingga saya tidak dapat memposting ini sebagai jawabannya, hanya mengedit pertanyaan. Berikan suara untuk membuka kembali pertanyaan ini. Untuk C #, saya menggunakan Xamarin.Android Ver. 4.7.09001 (beta). Kode sumber, semua data yang saya gunakan untuk menguji dan menyusun paket APK ada di GitHub:
Java: https://github.com/gregko/TtsSetup_Java
C #: https://github.com/gregko/TtsSetup_C_sharp
Jika seseorang ingin mengulang pengujian saya pada perangkat atau emulator lain, saya akan tertarik untuk mempelajari hasilnya juga.
Hasil dari pengujian saya
Saya memindahkan kelas ekstraktor kalimat ke C # (dari aplikasi @Voice Aloud Reader) dan menjalankan beberapa tes pada 10 file HTML dalam bahasa Inggris, Rusia, Prancis, Polandia, dan Ceko. Setiap proses dilakukan 5 kali pada semua 10 file, dan total waktu untuk 3 perangkat berbeda dan satu emulator diposting di bawah ini. Saya menguji "Rilis" hanya build, tanpa debugging diaktifkan.
HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM
Java: Total waktu keseluruhan (5 kali berjalan): 12361 ms, dengan total pembacaan file: 13304 ms
C #: Total waktu keseluruhan (5 kali berjalan): 17504 ms, dengan total pembacaan file: 17956 ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM
Java: Total waktu keseluruhan (5 kali berjalan): 8947 ms, dengan total pembacaan file: 9186 ms
C #: Total waktu keseluruhan (5 kali berjalan): 9884 ms, dengan total pembacaan file: 10247 ms
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM
Java: Total waktu keseluruhan (5 kali berjalan): 9742 ms, dengan total pembacaan file: 10111 ms
C #: Total waktu keseluruhan (5 kali berjalan): 10459 ms, dengan total pembacaan file: 10696 ms
Emulator - Intel (Android 4.2, API 17)
Java: Total waktu keseluruhan (5 kali berjalan): 2699 ms, dengan total pembacaan file: 3127 ms
C #: Total waktu keseluruhan (5 kali berjalan): 2049 ms, dengan total pembacaan file: 2182 ms
Emulator - Intel (Android 2.3.7, API 10)
Java: Total waktu keseluruhan (5 kali berjalan): 2992 ms, dengan total pembacaan file: 3591 ms
C #: Total waktu keseluruhan (5 kali berjalan): 2049 ms, dengan total pembacaan file: 2257 ms
Emulator - Arm (Android 4.0.4, API 15)
Java: Total waktu keseluruhan (5 kali berjalan): 41751 ms, dengan total pembacaan file: 43866 ms
C #: Total waktu keseluruhan (5 kali berjalan): 44136 ms, dengan total pembacaan file: 45109 ms
Diskusi singkat
Kode pengujian saya sebagian besar berisi penguraian teks, penggantian, dan pencarian Regex, mungkin untuk kode lain (mis. Operasi yang lebih numerik) hasilnya akan berbeda. Pada semua perangkat dengan prosesor ARM, Java berkinerja lebih baik daripada kode Xamarin C #. Perbedaan terbesar adalah di bawah Android 2.3, di mana kode C # berjalan sekitar. 70% dari kecepatan Java.
Pada emulator Intel (dengan teknologi Intel HAX, emulator berjalan dalam mode cepat), kode Xamarin C # menjalankan kode sampel saya jauh lebih cepat daripada Java - sekitar 1,35 kali lebih cepat. Mungkin Mono kode mesin virtual dan perpustakaan jauh lebih baik dioptimalkan pada Intel daripada pada ARM?
Edit 8 Juli 2013
Saya baru saja menginstal emulator Android Genymotion, yang berjalan di Oracle VirtualBox, dan sekali lagi ini menggunakan prosesor Intel asli, bukan meniru prosesor ARM. Seperti halnya emulator Intel HAX, sekali lagi C # berjalan di sini jauh lebih cepat. Inilah hasil saya:
Emulator Genymotion - Intel (Android 4.1.1, API 16)
Java: Total waktu keseluruhan (5 kali berjalan): 2069 ms, dengan total pembacaan file: 2248 ms
C #: Total waktu keseluruhan (5 kali berjalan): 1543 ms, dengan total pembacaan file: 1642 ms
Saya kemudian memperhatikan bahwa ada pembaruan untuk Xamarin. Android beta, versi 4.7.11, dengan catatan rilis menyebutkan beberapa perubahan dalam runtime Mono juga. Memutuskan untuk dengan cepat menguji beberapa perangkat ARM, dan kejutan besar - nomor C # membaik:
BN Nook XD +, ARM (Android 4.0)
Java: Total waktu keseluruhan (5 kali berjalan): 8103 ms, dengan total pembacaan file: 8569 ms
C #: Total waktu keseluruhan (5 kali berjalan): 7951 ms, dengan total pembacaan file: 8161 ms
Wow! C # sekarang lebih baik dari Java? Memutuskan untuk mengulang tes pada Galaxy Note 2 saya:
Samsung Galaxy Note 2 - ARM (Android 4.1.1)
Java: Total waktu keseluruhan (5 kali berjalan): 9675 ms, dengan total pembacaan file: 10028 ms
C #: Total waktu keseluruhan (5 kali berjalan): 9911 ms, dengan total pembacaan file: 10104 ms
Di sini C # tampaknya hanya sedikit lebih lambat, tetapi angka-angka ini memberi saya jeda: Mengapa waktunya lebih lama dari pada Nook HD +, meskipun Note 2 memiliki prosesor yang lebih cepat? Jawabannya: mode hemat daya. Pada Nook, itu dinonaktifkan, pada Catatan 2 - diaktifkan. Memutuskan untuk menguji dengan mode hemat daya dinonaktifkan (seperti yang diaktifkan, itu juga membatasi kecepatan prosesor):
Samsung Galaxy Note 2 - ARM (Android 4.1.1), hemat daya dinonaktifkan
Java: Total waktu keseluruhan (5 kali berjalan): 7153 ms, dengan total pembacaan file: 7459 ms
C #: Total waktu keseluruhan (5 kali berjalan): 6906 ms, dengan total pembacaan file: 7070 ms
Sekarang, secara mengejutkan, C # sedikit lebih cepat dari Java pada prosesor ARM juga. Perbaikan besar!
Edit 12 Juli 2013
Kita semua tahu, bahwa tidak ada yang mengalahkan kode asli untuk kecepatan, dan saya tidak puas dengan kinerja pemecah kalimat saya di Jawa atau C #, terutama yang saya perlukan untuk memperbaikinya (dan dengan demikian membuatnya lebih lambat). Memutuskan untuk menulis ulang dalam C ++. Berikut ini adalah perbandingan kecil (yaitu kumpulan file yang lebih kecil dari pengujian sebelumnya, untuk alasan lain) dari kecepatan native vs Java pada Galaxy Note 2 saya, dengan mode hemat daya dinonaktifkan:
Java: Total waktu keseluruhan (5 kali berjalan): 3292 ms, dengan total pembacaan file: 3454 ms
Ibu jari asli: Total waktu keseluruhan (5 kali berjalan): 537 ms, dengan total pembacaan file: 657 ms
Lengan asli: Total waktu keseluruhan (5 kali berjalan): 458 ms, dengan total pembacaan file: 587 ms
Sepertinya untuk tes khusus saya, kode asli adalah 6 sampai 7 kali lebih cepat daripada Java. Peringatan: tidak dapat menggunakan std :: regex class di Android, jadi harus menulis rutinitas khusus saya sendiri untuk mencari paragraf istirahat atau tag html. Tes awal saya untuk kode yang sama pada PC menggunakan regex, sekitar 4 hingga 5 kali lebih cepat daripada Java.
Fiuh! Bangun memori mentah dengan pointer char * atau wchar * lagi, saya langsung merasa 20 tahun lebih muda! :)
Edit 15 Juli 2013
(Silakan lihat di bawah, dengan pengeditan 7/30/2013, untuk hasil yang lebih baik dengan Dot42)
Dengan sedikit kesulitan, saya berhasil memport tes C # saya ke Dot42 (versi 1.0.1.71 beta), platform C # lainnya untuk Android. Hasil awal menunjukkan bahwa kode Dot42 sekitar 3x (3 kali) lebih lambat dari Xamarin C # (v. 4.7.11), pada emulator Intel Android. Satu masalah adalah kelas System.Text.RegularExpressions di Dot42 tidak memiliki fungsi Split () yang saya gunakan dalam tes Xamarin, jadi saya menggunakan kelas Java.Util.Regex sebagai gantinya, dan Java.Util.Regex.Pattern.Split () , jadi di tempat khusus ini dalam kode, ada perbedaan kecil ini. Seharusnya tidak menjadi masalah besar. Dot42 mengkompilasi ke kode Dalvik (DEX), sehingga bekerja sama dengan Java pada Android secara native, tidak perlu interop mahal dari C # ke Java seperti Xamarin.
Sebagai perbandingan, saya juga menjalankan tes pada perangkat ARM - di sini kode Dot42 "hanya" 2x lebih lambat dari Xamarin C #. Inilah hasil saya:
HTC Nexus One Android 2.3.7 (ARM)
Java: Total waktu keseluruhan (5 kali berjalan): 12187 ms, dengan total pembacaan file: 13200 ms
Xamarin C #: Total waktu keseluruhan (5 kali berjalan): 13935 ms, dengan total pembacaan file: 14465 ms
Dot42 C #: Total waktu keseluruhan (5 kali berjalan): 26000 ms, dengan total pembacaan file: 27168 ms
Samsung Galaxy Note 2, Android 4.1.1 (ARM)
Java: Total waktu keseluruhan (5 kali berjalan): 6895 ms, dengan total pembacaan file: 7275 ms
Xamarin C #: Total waktu keseluruhan (5 kali berjalan): 6466 ms, dengan total pembacaan file: 6720 ms
Dot42 C #: Total waktu keseluruhan (5 kali berjalan): 11185 ms, dengan total pembacaan file: 11843 ms
Intel emulator, Android 4.2 (x86)
Java: Total waktu keseluruhan (5 kali berjalan): 2389 ms, dengan total pembacaan file: 2770 ms
Xamarin C #: Total waktu keseluruhan (5 kali berjalan): 1748 ms, dengan total pembacaan file: 1933 ms
Dot42 C #: Total waktu keseluruhan (5 kali berjalan): 5150 ms, dengan total pembacaan file: 5459 ms
Bagi saya, itu juga menarik untuk dicatat bahwa Xamarin C # sedikit lebih cepat dari Java pada perangkat ARM yang lebih baru dan sedikit lebih lambat pada Nexus One yang lama. Jika ada yang ingin menjalankan tes ini juga, beri tahu saya dan saya akan memperbarui sumber di GitHub. Akan sangat menarik untuk melihat hasil dari perangkat Android nyata dengan prosesor Intel.
Perbarui 7/26/2013
Hanya pembaruan cepat, disusun ulang oleh aplikasi benchmark dengan Xamarin.Android 4.8 terbaru, dan juga dengan pembaruan dot42 1.0.1.72 yang dirilis hari ini - tidak ada perubahan signifikan dari hasil yang dilaporkan sebelumnya.
Perbarui 7/30/2013 - hasil yang lebih baik untuk dot42
Uji ulang Dot42 dengan port Robert (dari pembuat dot42) kode Java saya ke C #. Pada port C # saya yang awalnya dilakukan untuk Xamarin, saya mengganti beberapa kelas Java asli, seperti ListArray, dengan kelas List asli ke C #, dll. Robert tidak memiliki kode sumber Dot42 saya, jadi ia porting lagi dari Jawa dan menggunakan kelas Java asli di tempat-tempat seperti itu, yang menguntungkan Dot42, saya kira karena berjalan di Dalvik VM, seperti Jawa, dan bukan di Mono, seperti Xamarin. Sekarang hasil Dot42 jauh lebih baik. Berikut ini adalah log dari pengujian saya:
7/30/2013 - Dot42 menguji dengan lebih banyak kelas Java di Dot42 C #
Intel emulator, Android 4.2
Dot42, Greg's Code menggunakan StringBuilder.Replace () (seperti pada Xamarin):
Total waktu keseluruhan (5 kali berjalan): 3646 ms, dengan total pembacaan file: 3830 msDot42, Greg's Code menggunakan String.Replace () (seperti pada kode Java dan Robert):
Total waktu keseluruhan (5 kali): 3027 ms, dengan total pembacaan file: 3206 msDot42, Kode Robert:
Total waktu keseluruhan (5 kali berjalan): 1781 ms, dengan total pembacaan file: 1999 msXamarin:
Total waktu keseluruhan (5 kali berjalan): 1373 ms, dengan total pembacaan file: 1505 msJava:
Total waktu keseluruhan (5 kali berjalan): 1841 ms, dengan total pembacaan file: 2044 msARM, Samsung Galaxy Note 2, hemat daya, Android 4.1.1
Dot42, Greg's Code menggunakan StringBuilder.Replace () (seperti pada Xamarin):
Total waktu keseluruhan (5 kali berjalan): 10875 ms, dengan total pembacaan file: 11280 msDot42, Greg's Code menggunakan String.Replace () (seperti dalam Java dan Robert's code):
Total waktu keseluruhan (5 berjalan): 9710 ms, dengan total pembacaan file: 10097 msDot42, Kode Robert:
Total waktu keseluruhan (5 kali): 6279 ms, dengan total pembacaan file: 6622 msXamarin:
Total waktu keseluruhan (5 kali berjalan): 6201 ms, dengan total pembacaan file: 6476 msJava:
Total waktu keseluruhan (5 kali berjalan): 7141 ms, dengan total pembacaan file: 7479 ms
Saya masih berpikir bahwa Dot42 masih harus menempuh jalan panjang. Memiliki kelas seperti Java (mis. ArrayList) dan kinerja yang baik dengannya akan membuat kode porting dari Java ke C # sedikit lebih mudah. Namun, ini adalah sesuatu yang tidak mungkin saya lakukan banyak. Saya lebih suka ingin menggunakan kode C # yang ada (perpustakaan dll), yang akan menggunakan kelas C # asli (misalnya Daftar), dan itu akan berkinerja lambat dengan kode dot42 saat ini, dan sangat baik dengan Xamarin.
Greg