Quelqu’un at-il des benchmarks (code et résultats) comparant les performances des applications Android écrites en Xamarin C # et Java?

Je suis tombé sur Xamarin prétend que leur implémentation Mono sur Android et leurs applications compilées C # sont plus rapides que le code Java. Quelqu’un a-t-il effectué des tests sur des codes Java et C # très similaires sur différentes plates-formes Android afin de vérifier ces affirmations, pourrait-il publier le code et les résultats?

Ajouté le 18 juin 2013

Comme il n’y avait pas de réponse et ne pouvait pas trouver de tels points de repère fait par d’autres, a décidé de faire mes propres tests. Malheureusement, ma question rest “verrouillée”, je ne peux donc pas l’envoyer comme réponse, seulement modifier la question. S’il vous plaît voter pour rouvrir cette question. Pour C #, j’ai utilisé Xamarin.Android ver. 4.7.09001 (bêta). Le code source, toutes les données utilisées pour les tests et les packages APK compilés sont sur GitHub:

Java: https://github.com/gregko/TtsSetup_Java

C #: https://github.com/gregko/TtsSetup_C_sharp

Si quelqu’un souhaite répéter mes tests sur d’autres appareils ou émulateurs, je serais également intéressé à en connaître les résultats.

Résultats de mes tests

J’ai porté ma classe d’extracteur de phrases sur C # (depuis mon application @Voice Aloud Reader) et j’ai effectué des tests sur 10 fichiers html en anglais, russe, français, polonais et tchèque. Chaque exécution a été effectuée 5 fois sur les 10 fichiers, et le temps total pour 3 appareils différents et un émulateur est affiché ci-dessous. J’ai testé les versions “Release” uniquement, sans débogage activé.

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

Java: durée totale maximale (5 exécutions): 12361 ms, avec lecture totale du fichier: 13304 ms

C #: Temps total général (5 exécutions): 17504 ms, avec lecture totale du fichier: 17956 ms

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

Java: durée totale maximale (5 exécutions): 8947 ms, avec lecture totale du fichier: 9186 ms

C #: Durée totale totale (5 exécutions): 9884 ms, avec lecture totale du fichier: 10247 ms

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

Java: durée totale maximale (5 exécutions): 9742 ms, avec lecture totale du fichier: 10111 ms

C #: Temps total général (5 exécutions): 10459 ms, avec lecture du fichier total: 10696 ms

Emulateur – Intel (Android 4.2, API 17)

Java: durée totale maximale (5 exécutions): 2699 ms, avec lecture totale du fichier: 3127 ms

C #: durée totale totale (5 exécutions): 2049 ms, avec lecture totale du fichier: 2182 ms

Emulateur – Intel (Android 2.3.7, API 10)

Java: durée totale maximale (5 exécutions): 2992 ms, avec lecture totale du fichier: 3591 ms

C #: Durée totale totale (5 exécutions): 2049 ms, avec lecture totale du fichier: 2257 ms

Emulateur – Bras (Android 4.0.4, API 15)

Java: durée totale maximale (5 exécutions): 41751 ms, avec lecture totale du fichier: 43866 ms

C #: Durée totale totale (5 exécutions): 44136 ms, avec lecture totale du fichier: 45109 ms

Brève discussion

Mon code de test contient principalement l’parsing de texte, le remplacement et les recherches Regex, peut-être pour un autre code (par exemple des opérations plus numériques), les résultats seraient différents. Sur tous les appareils dotés de processeurs ARM, Java fonctionnait mieux que le code Xamarin C #. La plus grande différence était sous Android 2.3, où le code C # tourne à env. 70% de la vitesse Java.

Sur les émulateurs Intel (avec la technologie Intel HAX, l’émulateur s’exécute en mode virtuel rapide), le code Xamarin C # exécute mon code beaucoup plus rapidement que Java – environ 1,35 fois plus rapidement. Peut-être que le code de la machine virtuelle Mono et les bibliothèques sont bien mieux optimisés sur Intel que sur ARM?

Modifier le 8 juillet 2013

Je viens d’installer l’émulateur Android Genymotion, qui s’exécute dans Oracle VirtualBox, et là encore, celui-ci utilise un processeur Intel natif, n’émulant pas de processeur ARM. Comme avec l’émulateur Intel HAX, encore une fois, C # s’exécute beaucoup plus rapidement. Voici mes résultats:

Emulateur Genymotion – Intel (Android 4.1.1, API 16)

Java: durée totale maximale (5 exécutions): 2069 ms, avec lecture totale du fichier: 2248 ms

C #: Durée totale totale (5 exécutions): 1543 ms, avec lecture totale du fichier: 1642 ms

J’ai ensuite remarqué qu’il y avait une mise à jour vers la version bêta de Xamarin.Android, version 4.7.11, avec des notes de publication mentionnant également certains changements dans le runtime Mono. Nous avons décidé de tester rapidement certains périphériques ARM, et la grande surprise: les numéros C # ont été améliorés:

BN Nook XD +, ARM (Android 4.0)

Java: durée totale maximale (5 exécutions): 8103 ms, avec lecture du fichier total: 8569 ms

C #: Durée totale totale (5 exécutions): 7951 ms, avec lecture totale du fichier: 8161 ms

Hou la la! C # est maintenant meilleur que Java? Décidé de répéter le test sur mon Galaxy Note 2:

Samsung Galaxy Note 2 – ARM (Android 4.1.1)

Java: durée totale maximale (5 exécutions): 9675 ms, avec lecture totale du fichier: 10028 ms

C #: Durée totale totale (5 exécutions): 9911 ms, avec lecture totale du fichier: 10104 ms

Ici, C # semble être légèrement plus lent, mais ces chiffres m’ont donné une pause: pourquoi le temps est-il plus long que sur Nook HD +, même si la note 2 a un processeur plus rapide? La réponse: mode d’économie d’énergie. Sur Nook, il était désactivé, sur la note 2 – activé. Décidé de tester avec le mode d’économie d’énergie désactivé (comme avec activé, cela limite également la vitesse du processeur):

Samsung Galaxy Note 2 – ARM (Android 4.1.1), économie d’énergie désactivée

Java: durée totale maximale (5 exécutions): 7153 ms, avec lecture totale du fichier: 7459 ms

C #: durée totale totale (5 exécutions): 6906 ms, avec lecture totale du fichier: 7070 ms

Maintenant, étonnamment, C # est légèrement plus rapide que le processeur Java sur ARM. Grande amélioration!

Modifier le 12 juillet 2013

Nous soaps tous que rien ne vaut le code natif pour la vitesse, et je n’étais pas satisfait des performances de mon séparateur de phrases en Java ou en C #, en particulier le fait de devoir l’améliorer (et donc le ralentir). Décidé de le ré-écrire en C ++. Voici une petite comparaison (c.-à-d. Un ensemble plus restreint de fichiers que les tests antérieurs, pour d’autres raisons) de la vitesse du natif par rapport à Java sur mon Galaxy Note 2, avec le mode économie d’énergie désactivé:

Java: durée totale maximale (5 exécutions): 3292 ms, avec lecture totale du fichier: 3454 ms

Pouce natif: Durée totale totale (5 exécutions): 537 ms, avec lecture totale du fichier: 657 ms

Bras natif: Durée totale totale (5 exécutions): 458 ms, avec lecture totale du fichier: 587 ms

Pour mon test particulier, le code natif est 6 à 7 fois plus rapide que Java. Attention: ne pouvait pas utiliser la classe std :: regex sur Android, alors j’ai dû écrire mes propres routines spécialisées pour rechercher des sauts de paragraphes ou des balises HTML. Mes premiers tests du même code sur un PC utilisant regex étaient environ 4 à 5 fois plus rapides que Java.

Phew! En réveillant la mémoire brute avec des pointeurs de char * ou de wchar *, je me sentais instantanément plus jeune de 20 ans! 🙂

Modifier le 15 juillet 2013

(Voir ci-dessous, avec modifications du 30/07/2013, pour de meilleurs résultats avec Dot42)

Avec quelques difficultés, j’ai décidé de porter mes tests C # sur Dot42 (version 1.0.1.71 beta), une autre plate-forme C # pour Android. Les résultats préliminaires montrent que le code Dot42 est environ 3 fois (3 fois) plus lent que Xamarin C # (v. 4.7.11), sur un émulateur Android Intel. L’un des problèmes est que la classe System.Text.RegularExpressions de Dot42 n’a pas la fonction Split () que j’ai utilisée dans les tests Xamarin. J’ai donc utilisé la classe Java.Util.Regex et Java.Util.Regex.Pattern.Split ( ), dans ce lieu particulier du code, il y a cette petite différence. Ne devrait pas être un gros problème cependant. Dot42 comstack en code Dalvik (DEX), donc il coopère avec Java sur Android de manière native, ne nécessite pas d’interopérabilité coûteuse de C # à Java comme Xamarin.

Juste à titre de comparaison, je lance également le test sur les périphériques ARM – ici, le code Dot42 est “seulement” 2 fois plus lent que le code Xamarin C #. Voici mes résultats:

HTC Nexus One Android 2.3.7 (ARM)

Java: durée totale maximale (5 exécutions): 12187 ms, avec lecture totale du fichier: 13200 ms

Xamarin C #: Durée totale maximale (5 exécutions): 13935 ms, avec lecture totale du fichier: 14465 ms

Dot42 C #: Durée totale totale (5 exécutions): 26000 ms, avec lecture totale du fichier: 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: durée totale maximale (5 exécutions): 6895 ms, avec lecture totale du fichier: 7275 ms

Xamarin C #: Temps total total (5 exécutions): 6466 ms, avec lecture du fichier total: 6720 ms

Dot42 C #: Durée totale totale (5 exécutions): 11185 ms, avec lecture totale du fichier: 11843 ms

Émulateur Intel, Android 4.2 (x86)

Java: durée totale maximale (5 exécutions): 2389 ms, avec lecture totale du fichier: 2770 ms

Xamarin C #: Temps total total (5 exécutions): 1748 ms, avec le total de lecture du fichier: 1933 ms

Dot42 C #: Durée totale totale (5 exécutions): 5150 ms, avec lecture totale du fichier: 5459 ms

Pour moi, il était également intéressant de noter que Xamarin C # est légèrement plus rapide que Java sur un périphérique ARM plus récent, et légèrement plus lent sur l’ancien Nexus One. Si quelqu’un souhaite également effectuer ces tests, faites-le moi savoir et je mettrai à jour les sources sur GitHub. Il serait particulièrement intéressant de voir les résultats d’un véritable appareil Android équipé d’un processeur Intel.

Mise à jour 26/07/2013

Juste une mise à jour rapide, recompilée par les applications de référence avec la dernière version de Xamarin.Android 4.8, ainsi qu’avec la mise à jour dot42 1.0.1.72 publiée aujourd’hui – aucune modification significative par rapport aux résultats rapportés précédemment.

Mise à jour 30/07/2013 – meilleurs résultats pour dot42

Re-testé Dot42 avec le port de Robert (de dot42 makers) de mon code Java en C #. Dans mon port C # effectué initialement pour Xamarin, j’ai remplacé certaines classes Java natives, comme ListArray, par une classe List native de C #, etc. Robert n’avait pas mon code source Dot42, donc il le portait depuis Java et utilisait des classes Java originales. Je suppose que de tels endroits profitent à Dot42, car il fonctionne sur les machines virtuelles de Dalvik, comme Java, et non sur Mono, comme Xamarin. Maintenant, les résultats de Dot42 sont bien meilleurs. Voici un journal de mes tests:

30/07/2013 – Tests Dot42 avec plus de classes Java dans Dot42 C #

Émulateur Intel, Android 4.2

Dot42, le code de Greg utilisant SsortingngBuilder.Replace () (comme dans Xamarin):
Temps total total (5 passages): 3646 ms, avec lecture totale du fichier: 3830 ms

Dot42, le code de Greg utilisant Ssortingng.Replace () (comme dans Java et le code de Robert):
Durée totale totale (5 exécutions): 3027 ms, avec lecture totale du fichier: 3206 ms

Dot42, le code de Robert:
Temps total total (5 exécutions): 1781 ms, avec lecture totale du fichier: 1999 ms

Xamarin:
Temps total total (5 exécutions): 1373 ms, avec lecture du fichier total: 1505 ms

Java:
Temps total total (5 exécutions): 1841 ms, avec lecture totale du fichier: 2044 ms

ARM, Samsung Galaxy Note 2, économie d’énergie, Android 4.1.1

Dot42, le code de Greg utilisant SsortingngBuilder.Replace () (comme dans Xamarin):
Durée totale totale (5 exécutions): 10875 ms, avec lecture totale du fichier: 11280 ms

Dot42, le code de Greg utilisant Ssortingng.Replace () (comme dans Java et le code de Robert):
Durée totale totale (5 exécutions): 9710 ms, avec lecture totale du fichier: 10097 ms

Dot42, le code de Robert:
Durée totale totale (5 exécutions): 6279 ms, avec le total de lecture du fichier: 6622 ms

Xamarin:
Durée totale totale (5 exécutions): 6201 ms, avec lecture totale du fichier: 6476 ms

Java:
Durée totale totale (5 exécutions): 7141 ms, avec lecture totale du fichier: 7479 ms

Je pense toujours que Dot42 a un long chemin à parcourir. Avoir des classes de type Java (par exemple ArrayList) et une bonne performance avec celles-ci faciliterait légèrement le portage du code de Java vers C #. Cependant, c’est quelque chose que je ne serais pas susceptible de faire beaucoup. Je préférerais plutôt utiliser le code C # existant (bibliothèques, etc.), qui utilisera les classes C # natives (par exemple List), et cela fonctionnerait lentement avec le code dot42 actuel, et très bien avec Xamarin.

Greg

Ouais, la machine virtuelle Mono de Xamarin est plus impressionnante que Dalvik de Google utilisée dans Android. Je l’ai testé avec les tablettes HTC Flyer et Acer Iconia Tab pour comparer le port C # d’Android à Mono contre Java Dalvik, avec l’implémentation C # d’Android et le véritable déblocage de Dalvik basé sur Java.

I came across this interesting post 

https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz

Performances des applications Android

Performance de l'application iOS

J’espère que cette information aide.

Ceci est un autre article de blog plus actualisé que j’aimerais partager avec vous . Il compare Xamarin au code natif et à Cordova sur IOs et Android.

En bref, Xamarin fonctionne parfois mieux que le code natif. Il a testé la taille de l’application, les temps de chargement, le chargement d’une liste à partir du service Azure et le calcul des nombres premiers.

Prendre plaisir!

Edit: J’ai mis à jour le lien mort et j’ai remarqué qu’il y avait une partie 2

Nous avons récemment étudié l’utilisation de Xamarin pour une application. Nous avons utilisé le code C # que nous avions déjà écrit pour la version Windows RT de notre application. Certains détails spécifiques devaient être réécrits pour la version Android.

Nous avons découvert que les E / S dans Xamarin C # sont environ 2 fois plus lentes que Java. Notre application est fortement liée aux E / S. Nous n’en avons pas encore découvert la cause, mais pour le moment, nous supposons que cela est dû à un marshaling. Bien que nous essayions de restr dans la VM Mono la plupart du temps, nous ne soaps pas comment Mono accède réellement au disque.

Cela dit aussi que notre code C # utilise SQLite.NET ( https://github.com/praeclarum/sqlite-net ). Les extractions identiques à l’aide du code SQLite.NET sont également deux fois plus lentes que l’utilisation de l’encapsuleur Java SQLite d’Android. Après avoir examiné le code source, il semble se lier directement au fichier .dll, donc je ne sais pas pourquoi il est beaucoup plus lent. Une possibilité est que le marshaling des chaînes de natif en Java soit plus rapide sous Android que natif en C # sur Xamarin.

Voici quelques informations que j’ai trouvées dans un autre test entre les solutions natives, Xamarin et Xamarin.Forms (les tests incluent également les performances iOS) sur les deux périphériques suivants:

Samsung Galaxy A7 : Version Android OS: 6.0 Unité centrale: Octa-core 1,9 GHz Cortex-A53 RAM: 3 Go Résolution de l’écran: 1920 × 1080

iPhone 6s : version iOS: 10.3.3 Unité centrale: Twister double cœur 1,84 GHz: 2 Go Résolution de l’écran: 1334 × 750

La comparaison est faite sur quelques fonctionnalités communes, chacune avec sa propre application:

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

Chaque test est répété plusieurs fois, les graphiques montrent les résultats moyens.


Bonjour le monde

Comparaison de performance Basic Hellow World


Rest Rest API

Ensemble de tests visant à mesurer le temps nécessaire à l’application pour envoyer une demande via l’API REST et recevoir la réponse sans traitement supplémentaire, à l’aide de l’API OpenWeatherMap.

Comparaison des performances de l'API Rest


Opérations JSON Tests réalisés à l’aide du framework Newtonsoft Json.net pour sérialiser et désérialiser des objects JSON dans toutes les applications Xamarin. Sérialisation et désérialisation Android natives testées à l’aide de deux bibliothèques Java: Jackson et GSON.

Deux courses sont effectuées, une première à partir de zéro et une seconde avec des informations et des opérations mises en cache

Première exécution :

Sérialisation JSON première exécution

Première désérialisation JSON

(Opérations natives iOS JSON est en train de tuer ce test btw, et Xamarin le rejoint dans le second)

Deuxième série de sérialisation JSON

Deuxième série de désérialisation JSON


Opérations photo

Premier chargement sur des images avec trois résolutions différentes:

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

Image Première charge Android

Image Première charge iOS

Quelque chose semblait incertain quant aux résultats de Xamarin.Forms pour ce test, il n’est donc pas inclus dans le graphique.


Opérations SQLite

Deux opérations testées:

 BulkInsert: Loading rows of data into a database table. GetAll: Resortingeving all data from the database. 

Avec des bases de données ayant 10 000 enregistrements. Toutes les opérations ont été traitées en interne sur les périphériques.

Performances SQLite Android

Performances SQLite iOS


Xamarin Native (Xamarin.iOS / Xamarin.Android) se présente comme de bonnes alternatives au code natif, alors que Xamarin.Forms semble lent dans de nombreux cas, mais cela peut être une très bonne solution pour développer rapidement des applications très simples.

Le test complet provient de cette source:

https://www.altexsoft.com/blog/engineering/performance-comparison-xamarin-forms-xamarin-ios-xamarin-android-vs-android-and-ios-native-applications/

Merci de m’avoir donné les explications pour améliorer ma réponse, j’espère que cela vous aidera un peu 🙂

Performance

La performance est un mot vague si vous ne définissez pas ce que vous entendez par performance, si la performance de calcul est simple, Xamarin peut être plus rapide que Java en fonction de la nature du calcul.

Android est livré avec des formes multiples pour exécuter du code dans:

  • RenderScript (CPU et GPU)
  • Java (SDK)
  • C ++ (NDK)
  • OpenGL (GPU)

Il est évident que lors de l’exécution du code, plus la solution est native, plus elle sera rapide. Un langage basé sur l’exécution ne battra jamais un langage qui s’exécute directement sur le processeur.

Mais d’un autre côté, si vous souhaitez mesurer les performances réelles d’utilisation, Java sera plus rapide que Xamarin.

Xamarin et pourquoi il peut être plus lent

Lorsque vous comparez Xamarin à de vieilles applications Java, les performances peuvent être plus rapides pour Xamarin, car elles peuvent être plus lentes.

Dans un exemple réel, les applications Xamarin sont très probablement plus lentes que les applications Java, car de nombreux appels Android / Java (système) doivent être delegates depuis et vers l’exécution Xamarin en utilisant ce que l’on appelle des liaisons.

Il existe plusieurs types de liaisons importants à connaître:

  • JNI (Java Native Interface): liaison utilisée dans de nombreuses applications Android pour assurer l’interface entre le code Java (SDK) et le code C ++ natif (NDK).
  • MCW (Managed Callable Wrappers): liaison disponible dans Xamarin pour s’interfacer du code C # géré au code Java (exécution Android).
  • ACW (Android Callable Wrappers): liaison disponible dans Xamarin pour s’interfacer du code Java (temps d’exécution Android) au code C # géré.

Plus d’informations sur MCW et ACW ici: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

Les liaisons sont très coûteuses en termes de performance. Invoquer une méthode C ++ à partir de Java ajoute une énorme charge au temps d’appel, appeler une méthode C ++ depuis C ++ est beaucoup plus rapide.

Quelqu’un a fait un test de performance pour calculer combien d’opérations Java en moyenne coûte un appel JNI: Quelle est la surcharge quantitative liée à la réalisation d’un appel JNI?

Mais non seulement les appels JNI sont coûteux, mais les appels depuis et vers MCW et ACW. Les applications Xamarin du monde réel effectuent de nombreux appels à l’aide de liaisons et, du fait de leur utilisation réelle, une application Xamarin peut être (et sera en général) plus lente qu’une ancienne application Java. Cependant, selon la conception de l’application Xamarin, il est fort probable que l’utilisateur ne remarquera même pas la différence.

TLDR / Conclusion: Xamarin doit utiliser toutes sortes de liaisons, ce qui est coûteux en temps.

Outre les liaisons, il existe de nombreux autres facteurs impliqués dans les performances du monde réel, par exemple la taille du fichier binary, le chargement de l’application en mémoire, les opérations d’E / S et bien d’autres. Un article de blog qui examine certaines de ces choses peut être trouvé ici: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms

Il est assez vieux tests mais pourrait être pertinent: https://github.com/EgorBo/Xamarin.Android-vs-Java

Test arithmétique

entrer la description de l'image ici

Collections, génériques, types de valeur personnalisés

entrer la description de l'image ici

Travailler avec des chaînes

entrer la description de l'image ici

UPD: nouvelles données avec Google Pixel 2 (merci yousha-aleayoub )

Test Pixel 2