Xamarin, Android'deki Mono uygulamalarının ve C # derlenmiş uygulamalarının Java kodundan daha hızlı olduğunu iddia etti. Herkes bu tür iddiaları doğrulamak için farklı Android platformlarında çok benzer Java ve C # kodlarında gerçek kriterler gerçekleştirdi mi, kodu ve sonuçları yayınlayabilir mi?
18 Haziran 2013 Eklendi
Cevap olmadığı ve başkaları tarafından yapılan bu tür ölçütleri bulamadığı için kendi testlerimi yapmaya karar verdim. Ne yazık ki, sorum "kilitli" kalıyor, bu yüzden bunu cevap olarak gönderemiyorum, sadece soruyu düzenleyeceğim. Bu soruyu yeniden açmak için lütfen oy verin. C # için Xamarin.Android Ver. 4.7.09001 (beta). Kaynak kodu, test etmek için kullandığım tüm veriler ve derlenmiş APK paketleri GitHub'da:
Java: https://github.com/gregko/TtsSetup_Java
C #: https://github.com/gregko/TtsSetup_C_sharp
Birisi testlerimi diğer cihazlarda veya emülatörlerde tekrarlamak isterse, sonuçları da öğrenmek isterim.
Test sonuçlarım
Cümle çıkarma sınıfımı C @ 'a (@Voice Aloud Reader uygulamamdan) taşıdım ve İngilizce, Rusça, Fransızca, Lehçe ve Çekçe dillerinde 10 HTML dosyasında bazı testler yaptım. Her çalışma 10 dosyada 5 kez gerçekleştirildi ve 3 farklı cihaz ve bir emülatör için toplam süre aşağıda yayınlandı. Hata ayıklama etkin olmadan yalnızca "Release" derlemelerini test ettim.
HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM
Java: Genel toplam süre (5 çalıştırma): 12361 ms, dosya okuma toplamı: 13304 ms
C #: Genel toplam süre (5 çalıştırma): 17504 ms, dosya okuma toplamıyla: 17956 ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM
Java: Genel toplam süre (5 çalıştırma): 8947 ms, dosya okuma toplamıyla: 9186 ms
C #: Genel toplam süre (5 çalıştırma): 9884 ms, dosya okuma toplamıyla: 10247 ms
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM
Java: Genel toplam süre (5 çalıştırma): 9742 ms, dosya okuma toplamıyla: 10111 ms
C #: Genel toplam süre (5 çalıştırma): 10459 ms, dosya okuma toplamıyla: 10696 ms
Emulator - Intel (Android 4.2, API 17)
Java: Genel toplam süre (5 çalıştırma): 2699 ms, dosya okuma toplamıyla: 3127 ms
C #: Genel toplam süre (5 çalıştırma): 2049 ms, dosya okuma toplamıyla: 2182 ms
Emulator - Intel (Android 2.3.7, API 10)
Java: Genel toplam süre (5 çalıştırma): 2992 ms, dosya okuma toplamıyla: 3591 ms
C #: Genel toplam süre (5 çalıştırma): 2049 ms, dosya okuma toplamıyla: 2257 ms
Emulator - Arm (Android 4.0.4, API 15)
Java: Genel toplam süre (5 çalıştırma): 41751 ms, dosya okuma toplamı: 43866 ms
C #: Genel toplam süre (5 çalıştırma): 44136 ms, dosya okuma toplamıyla: 45109 ms
Kısa tartışma
Test kodum çoğunlukla metin ayrıştırma, değiştirme ve Regex aramaları içeriyor, belki diğer kodlar için (örneğin daha fazla sayısal işlem) sonuçlar farklı olurdu. ARM işlemcili tüm cihazlarda Java, Xamarin C # kodundan daha iyi performans gösterdi. En büyük fark, C # kodunun yaklaşık olarak çalıştığı Android 2.3 altındaydı. Java hızının% 70'i.
Intel emülatöründe (Intel HAX teknolojisi ile emülatör hızlı erdem modunda çalışır), Xamarin C # kodu örnek kodumu Java'dan çok daha hızlı çalıştırır - yaklaşık 1,35 kat daha hızlı. Belki Mono sanal makine kodu ve kütüphaneleri Intel'de ARM'den çok daha iyi optimize edilmiştir?
Düzenle 8 Temmuz 2013
Oracle VirtualBox'ta çalışan Genymotion Android emülatörünü yeni kurdum ve yine bu, ARM işlemcisini taklit etmek yerine yerli Intel işlemci kullanıyor. Intel HAX emülatöründe olduğu gibi, yine C # burada çok daha hızlı çalışır. İşte sonuçlarım:
Genymotion emülatörü - Intel (Android 4.1.1, API 16)
Java: Genel toplam süre (5 çalıştırma): 2069 ms, dosya okuma toplamıyla: 2248 ms
C #: Genel toplam süre (5 çalıştırma): 1543 ms, dosya okuma toplamıyla: 1642 ms
Daha sonra Xamarin.Android beta, 4.7.11 sürümünde bir güncelleme olduğunu fark ettim ve sürüm notları Mono çalışma zamanında da bazı değişikliklerden bahsediyordu. Bazı ARM cihazlarını hızlı bir şekilde test etmeye karar verdi ve büyük sürpriz - C # numaraları geliştirildi:
BN Nook XD +, ARM (Android 4.0)
Java: Genel toplam süre (5 çalıştırma): 8103 ms, dosya okuma toplamıyla: 8569 ms
C #: Genel toplam süre (5 çalıştırma): 7951 ms, dosya okuma toplamıyla: 8161 ms
Vaov! C # şimdi Java daha iyidir? Testi Galaxy Note 2'mde tekrarlamaya karar verdim:
Samsung Galaxy Note 2 - ARM (Android 4.1.1)
Java: Genel toplam süre (5 çalıştırma): 9675 ms, dosya okuma toplamıyla: 10028 ms
C #: Genel toplam süre (5 çalıştırma): 9911 ms, dosya okuma toplamıyla: 10104 ms
Burada C # sadece biraz daha yavaş görünüyor, ancak bu sayılar bana bir duraklama verdi: Not 2'nin daha hızlı bir işlemcisi olmasına rağmen neden zaman Nook HD + 'dan daha uzun? Cevap: güç tasarrufu modu. Nook'ta, Not 2'de devre dışı bırakıldı. Güç tasarrufu modu devre dışıyken test etmeye karar verildi (etkin olduğu gibi işlemci hızını da sınırlar):
Samsung Galaxy Note 2 - ARM (Android 4.1.1), güç tasarrufu devre dışı
Java: Genel toplam süre (5 çalıştırma): 7153 ms, dosya okuma toplamıyla: 7459 ms
C #: Genel toplam süre (5 çalıştırma): 6906 ms, dosya okuma toplamıyla: 7070 ms
Şimdi, şaşırtıcı bir şekilde, C #, ARM işlemcisindeki Java'dan biraz daha hızlı. Büyük gelişme!
Düzenle 12 Temmuz 2013
Hepimiz biliyoruz ki, hiçbir şey hız için yerel kodu geçmez ve cümle splitter'ımın Java veya C #'daki performansından memnun kalmadım, özellikle de onu geliştirmem (ve böylece daha da yavaşlatmam) gerekiyor. C ++ ile yeniden yazmaya karar verdim. Burada, Galaxy Note 2 cihazımdaki yerel ve Java hızının güç tasarrufu modu devre dışı bırakıldığında küçük bir (yani önceki testlerden daha küçük bir dosya seti) karşılaştırması yapılmıştır:
Java: Genel toplam süre (5 çalıştırma): 3292 ms, dosya okuma toplamıyla: 3454 ms
Doğal başparmak: Genel toplam süre (5 çalıştırma): 537 ms, dosya okuma toplamı: 657 ms
Yerel kol: Genel toplam süre (5 çalıştırma): 458 ms, dosya okuma toplamı: 587 ms
Özel testime benziyor, yerel kod Java'dan 6 ila 7 kat daha hızlı. Dikkat: Android'de std :: regex sınıfını kullanamadı, bu yüzden paragraf sonlarını veya html etiketlerini arayan kendi özel rutinleri yazmak zorunda kaldım. Regex kullanan bir bilgisayarda aynı kodu ilk testlerim, Java'dan yaklaşık 4 ila 5 kat daha hızlıydı.
Uf! Ham belleği tekrar char * veya wchar * işaretçileriyle uyandırırken, anında 20 yaş daha genç hissettim! :)
Düzenle 15 Temmuz 2013
(Dot42 ile daha iyi sonuçlar almak için lütfen 7/30/2013 düzenlemeleriyle aşağıya bakın)
Bazı zorluklarla, C # testlerimi Android için başka bir C # platformu olan Dot42'ye (sürüm 1.0.1.71 beta) aktarmayı başardım. Ön sonuçlar, Intel Android öykünücüsünde Dot42 kodunun Xamarin C #'dan (v. 4.7.11) yaklaşık 3 kat (3 kat) daha yavaş olduğunu gösteriyor. Bir sorun, Dot42'deki System.Text.RegularExpressions sınıfının Xamarin testlerinde kullandığım Split () işlevine sahip olmaması, bu nedenle Java.Util.Regex sınıfını ve Java.Util.Regex.Pattern.Split () kullandım , yani koddaki bu özel yerde, bu küçük fark var. Yine de büyük bir sorun olmamalı. Dot42 Dalvik (DEX) kodunu derler, bu nedenle Android'de Java ile yerel olarak işbirliği yapar, C # 'dan Xamarin gibi Java'ya pahalı birlikte çalışma gerektirmez.
Sadece karşılaştırma için, ARM cihazlarında da testi çalıştırıyorum - burada Dot42 kodu Xamarin C # 'dan 2 kat daha yavaş. İşte sonuçlarım:
HTC Nexus One Android 2.3.7 (ARM)
Java: Genel toplam süre (5 çalıştırma): 12187 ms, dosya okuma toplamı: 13200 ms
Xamarin C #: Genel toplam süre (5 çalıştırma): 13935 ms, dosya okuma toplamıyla: 14465 ms
Dot42 C #: Genel toplam süre (5 çalıştırma): 26000 ms, dosya okuma toplamıyla: 27168 ms
Samsung Galaxy Note 2, Android 4.1.1 (ARM)
Java: Genel toplam süre (5 çalıştırma): 6895 ms, dosya okuma toplamıyla: 7275 ms
Xamarin C #: Genel toplam süre (5 çalıştırma): 6466 ms, dosya okuma toplamıyla: 6720 ms
Dot42 C #: Genel toplam süre (5 çalıştırma): 11185 ms, dosya okuma toplamıyla: 11843 ms
Intel emülatörü, Android 4.2 (x86)
Java: Genel toplam süre (5 çalıştırma): 2389 ms, dosya okuma toplamı: 2770 ms
Xamarin C #: Genel toplam süre (5 çalıştırma): 1748 ms, dosya okuma toplamı: 1933 ms
Dot42 C #: Genel toplam süre (5 çalıştırma): 5150 ms, dosya okuma toplamıyla: 5459 ms
Bana göre, Xamarin C # 'ın yeni bir ARM cihazında Java'dan biraz daha hızlı ve eski Nexus One'da biraz daha yavaş olduğunu belirtmek de ilginçti. Bu testleri de yapmak isteyen varsa, lütfen bana bildirin, ben de GitHub'daki kaynakları güncelleyeceğim. Intel işlemcili gerçek bir Android cihazdan sonuçları görmek özellikle ilginç olacaktır.
Güncelleme 26.07.2013
En son Xamarin.Android 4.8 ve bugün yayınlanan dot42 1.0.1.72 güncellemesi ile kıyaslama uygulamaları tarafından yeniden derlenen hızlı bir güncelleme - daha önce bildirilen sonuçlarda önemli bir değişiklik yok.
Güncelleme 7/30/2013 - dot42 için daha iyi sonuçlar
Dot42, Java kodumu Robert'ın (dot42 üreticilerinden) bağlantı noktasıyla C # 'a yeniden test etti. Başlangıçta Xamarin için yapılan C # portumda, ListArray gibi bazı yerel Java sınıflarını, C #'a özgü List sınıfı ile değiştirdim. Robert'in Dot42 kaynak kodum yoktu, bu yüzden tekrar Java'dan taşıdı ve orijinal Java sınıflarını kullandı. Dot42 yararlanan böyle yerler, sanırım çünkü Xamarin gibi Mono'da değil Java gibi Dalvik VM'de çalışıyor. Şimdi Dot42 sonuçları çok daha iyi. İşte benim test bir günlük:
30.07.2013 - Dot42 C #'da daha fazla Java sınıfı ile Dot42 testleri
Intel emülatörü, Android 4.2
Dot42, Greg'in Code kullanarak StringBuilder.Replace () (Xamarin'de olduğu gibi): Genel
toplam süre (5 çalıştırma): 3646 ms, dosya okuma toplamıyla: 3830 msDot42, Greg'in Code kullanarak String.Replace () (Java ve Robert kodunda olduğu gibi): Genel
toplam süre (5 çalıştırma): 3027 ms, dosya okuma toplamıyla: 3206 msDot42, Robert Kod: Genel
toplam süre (5 çalıştırma): 1781 ms, dosya okuma toplamı: 1999 msXamarin: Genel
toplam süre (5 çalıştırma): 1373 ms, dosya okuma toplamı: 1505 msJava: Genel
toplam süre (5 çalıştırma): 1841 ms, dosya okuma toplamıyla: 2044 msARM, Samsung Galaxy Note 2, güç tasarrufu, Android 4.1.1
Dot42, Greg'in Code: StringBuilder.Replace () (Xamarin'de olduğu gibi): Genel
toplam süre (5 çalıştırma): 10875 ms, dosya okuma toplamıyla: 11280 msDot42, Greg'in Code kullanarak String.Replace () (Java ve Robert kodunda olduğu gibi): Genel
toplam süre (5 çalıştırma): 9710 ms, dosya okuma toplamıyla: 10097 msDot42, Robert Kod: Genel
toplam süre (5 çalıştırma): 6279 ms, dosya okuma toplamı: 6622 msXamarin: Genel
toplam süre (5 çalıştırma): 6201 ms, dosya okuma toplamı: 6476 msJava: Genel
toplam süre (5 çalıştırma): 7141 ms, dosya okuma toplamı: 7479 ms
Hala Dot42'nin uzun bir yolu olduğunu düşünüyorum. Java benzeri sınıflara (örn. ArrayList) sahip olmak ve onlarla iyi bir performans sergilemek, Java'dan C #'a taşıma kodunu biraz daha kolay hale getirir. Ancak, bu çok fazla şey yapmayacağım bir şey. Daha çok yerel C # sınıflarını (örneğin Liste) kullanacak ve mevcut dot42 koduyla yavaşça çalışacak ve Xamarin ile çok iyi olan mevcut C # kodunu (kütüphaneler vb.) Kullanmak istiyorum.
Greg