566 votes

Quelqu'un dispose-t-il de benchmarks (code et résultats) comparant les performances d'applications Android écrites en C# et Java de Xamarin ?

Je suis tombé sur les affirmations de Xamarin selon lesquelles leur implémentation Mono sur Android et leurs applications compilées en C# sont plus rapides que le code Java. Est-ce que quelqu'un a effectué des benchmarks réels sur des codes Java et C# très similaires sur différentes plateformes Android pour vérifier ces affirmations, et a pu poster le code et les résultats ?

Ajouté le 18 juin 2013

Comme il n'y avait pas de réponse et que je n'ai pas pu trouver de tels benchmarks réalisés par d'autres, j'ai décidé de faire mes propres tests. Malheureusement, ma question reste "verrouillée" et je ne peux donc pas publier cette réponse, mais seulement modifier la question. Veuillez voter pour la réouverture de cette question. Pour C#, j'ai utilisé Xamarin.Android ver. 4.7.09001 (beta). Le code source, toutes les données que j'ai utilisées pour les tests, et les paquets 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 intéressé de connaître les résultats également.

Résultats de mes tests

J'ai porté ma classe d'extracteur de phrases en C# (à partir de mon application @Voice Aloud Reader) et j'ai effectué quelques tests sur 10 fichiers html en anglais, russe, français, polonais et tchèque. Chaque test a été effectué 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) - ROM CyanogenMod

Java : Temps total (5 exécutions) : 12361 ms, avec un total de lecture de fichier : 13304 ms

C# : Temps total (5 exécutions) : 17504 ms, avec un total de lecture de fichier : 17956 ms

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

Java : Temps total (5 exécutions) : 8947 ms, avec un total de lecture de fichier : 9186 ms

C# : Temps total (5 exécutions) : 9884 ms, avec un total de 10247 ms pour la lecture du fichier.

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

Java : Temps total (5 exécutions) : 9742 ms, avec un total de lecture de fichier : 10111 ms

C# : Temps total (5 exécutions) : 10459 ms, avec un total de lecture de fichier : 10696 ms

Emulateur - Intel (Android 4.2, API 17)

Java : Temps total (5 exécutions) : 2699 ms, avec un total de 3127 ms pour la lecture du fichier.

C# : Temps total (5 exécutions) : 2049 ms, avec un total de 2182 ms pour la lecture du fichier.

Emulateur - Intel (Android 2.3.7, API 10)

Java : Temps total (5 exécutions) : 2992 ms, avec un total de lecture de fichier : 3591 ms

C# : Temps total (5 exécutions) : 2049 ms, avec lecture du fichier total : 2257 ms

Emulateur - Arm (Android 4.0.4, API 15)

Java : Temps total (5 exécutions) : 41751 ms, avec un total de 43866 ms pour la lecture du fichier.

C# : Temps total (5 exécutions) : 44136 ms, avec un total de lecture de fichier : 45109 ms

Brève discussion

Mon code de test contient principalement des analyses de texte, des remplacements et des recherches Regex, peut-être que pour d'autres codes (par exemple, plus d'opérations numériques), les résultats seraient différents. Sur tous les appareils dotés de processeurs ARM, Java a donné de meilleurs résultats que le code C# de Xamarin. La plus grande différence a été constatée sous Android 2.3, où le code C# s'est exécuté à environ 70 % de la vitesse de Java.

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

Editer le 8 juillet 2013

Je viens d'installer l'émulateur Android Genymotion, qui fonctionne dans Oracle VirtualBox, et encore une fois celui-ci utilise le processeur Intel natif, pas l'émulation du processeur ARM. Comme avec l'émulateur Intel HAX, C# s'exécute ici aussi beaucoup plus rapidement. Voici mes résultats :

Émulateur Genymotion - Intel (Android 4.1.1, API 16)

Java : Temps total (5 exécutions) : 2069 ms, avec un total de lecture de fichier : 2248 ms

C# : Temps total (5 exécutions) : 1543 ms, avec un total de lecture de fichier : 1642 ms

J'ai ensuite remarqué qu'il y avait une mise à jour de la version bêta de Xamarin.Android, la version 4.7.11, avec des notes de publication mentionnant certains changements dans le runtime Mono également. J'ai décidé de tester rapidement quelques appareils ARM, et grosse surprise : les chiffres de C# se sont améliorés :

BN Nook XD+, ARM (Android 4.0)

Java : Temps total (5 exécutions) : 8103 ms, avec un total de 8569 ms pour la lecture du fichier.

C# : Temps total (5 exécutions) : 7951 ms, avec un total de lecture de fichier : 8161 ms

Wow ! C# est maintenant meilleur que Java ? J'ai décidé de répéter le test sur mon Galaxy Note 2 :

Samsung Galaxy Note 2 - ARM (Android 4.1.1)

Java : Temps total (5 exécutions) : 9675 ms, avec un total de lecture de fichier : 10028 ms

C# : Temps total (5 exécutions) : 9911 ms, avec lecture du fichier total : 10104 ms

Ici, le C# ne semble être que légèrement plus lent, mais ces chiffres m'ont fait réfléchir : Pourquoi le temps est plus long que sur le Nook HD+, même si le Note 2 a un processeur plus rapide ? La réponse : le mode économie d'énergie. Sur le Nook, il était désactivé, sur le Note 2 - activé. J'ai décidé de tester avec le mode d'économie d'énergie désactivé (comme s'il était activé, il limite également la vitesse du processeur) :

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

Java : Temps total (5 exécutions) : 7153 ms, avec un total de lecture de fichier : 7459 ms

C# : Temps total (5 exécutions) : 6906 ms, avec un total de 7070 ms pour la lecture du fichier.

Maintenant, étonnamment, C# est légèrement plus rapide que Java sur un processeur ARM également. Une grande amélioration !

Editer le 12 juillet 2013

Nous savons 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 C#, en particulier que je dois l'améliorer (et donc le rendre encore plus lent). J'ai décidé de le réécrire en C++. Voici une petite comparaison (c'est-à-dire un ensemble de fichiers plus petit que les tests précédents, pour d'autres raisons) de la vitesse du langage natif par rapport à Java sur mon Galaxy Note 2, avec le mode économie d'énergie désactivé :

Java : Temps total (5 exécutions) : 3292 ms, avec un total de lecture de fichier : 3454 ms

Pouce natif : Temps total (5 exécutions) : 537 ms, avec lecture du fichier total : 657 ms

Bras natif : Temps total (5 exécutions) : 458 ms, avec lecture de fichier total : 587 ms

Il semble que pour mon test particulier, le code natif soit 6 à 7 fois plus rapide que Java. Mise en garde : je n'ai pas pu utiliser la classe std::regex sur Android, j'ai donc dû écrire mes propres routines spécialisées pour rechercher les sauts de paragraphes ou les balises html. Mes premiers tests du même code sur un PC en utilisant regex, étaient environ 4 à 5 fois plus rapides que Java.

Ouf ! En réveillant à nouveau la mémoire brute avec des pointeurs char* ou wchar*, je me suis instantanément senti rajeuni de 20 ans ! :)

Editer le 15 juillet 2013

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

Avec quelques difficultés, j'ai réussi à porter mes tests C# vers Dot42 (version 1.0.1.71 beta), une autre plateforme C# pour Android. Les résultats préliminaires montrent que le code Dot42 est environ 3x (3 fois) plus lent que Xamarin C# (v. 4.7.11), sur un émulateur Intel Android. Un problème est que la classe System.Text.RegularExpressions dans Dot42 n'a pas la fonction Split() que j'ai utilisée dans les tests Xamarin, donc j'ai utilisé la classe Java.Util.Regex à la place, et Java.Util.Regex.Pattern.Split(), donc à cet endroit particulier du code il y a cette petite différence. Cela ne devrait pas être un gros problème. Dot42 compile en code Dalvik (DEX), donc il coopère avec Java sur Android de manière native, il n'a pas besoin d'une interopération coûteuse de C# à Java comme Xamarin.

À titre de comparaison, j'ai également effectué le test sur des appareils ARM - ici, le code Dot42 est "seulement" 2 fois plus lent que le C# de Xamarin. Voici mes résultats :

HTC Nexus One Android 2.3.7 (ARM)

Java : Temps total (5 exécutions) : 12187 ms, avec un total de lecture de fichier : 13200 ms

Xamarin C# : Temps total (5 exécutions) : 13935 ms, avec un total de lecture de fichier : 14465 ms

Dot42 C# : Temps total (5 exécutions) : 26000 ms, avec lecture du fichier total : 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java : Temps total (5 exécutions) : 6895 ms, avec un total de 7275 ms pour la lecture du fichier.

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

Dot42 C# : Temps total (5 exécutions) : 11185 ms, avec un total de lecture de fichier : 11843 ms

Émulateur Intel, Android 4.2 (x86)

Java : Temps total (5 exécutions) : 2389 ms, avec un total de 2770 ms pour la lecture du fichier.

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

Dot42 C# : Temps total (5 exécutions) : 5150 ms, avec un total de 5459 ms pour la lecture du fichier.

Il était également intéressant de noter que Xamarin C# est légèrement plus rapide que Java sur un appareil ARM récent, et légèrement plus lent sur le vieux 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 sur un vrai appareil Android avec un processeur Intel.

Mise à jour 7/26/2013

Juste une mise à jour rapide, recompilé par des applications de référence avec la dernière Xamarin.Android 4.8, et aussi avec la mise à jour dot42 1.0.1.72 publiée aujourd'hui - pas de changements significatifs par rapport aux résultats rapportés auparavant.

Mise à jour 7/30/2013 - meilleurs résultats pour dot42

J'ai re-testé Dot42 avec le portage par Robert (de dot42 makers) de mon code Java vers C#. Dans mon portage C# réalisé initialement pour Xamarin, j'ai remplacé certaines classes Java natives, comme ListArray, par la classe List native de C#, etc. Robert n'avait pas mon code source Dot42, il l'a donc porté à nouveau à partir de Java et a utilisé les classes Java originales à ces endroits, ce qui profite à Dot42, je suppose parce qu'il fonctionne dans Dalvik VM, comme Java, et non dans Mono, comme Xamarin. Maintenant, les résultats de Dot42 sont bien meilleurs. Voici un journal de mes tests :

30/07/2013 - Les tests de Dot42 avec plus de classes Java dans Dot42 C#

Émulateur Intel, Android 4.2

Dot42, le code de Greg utilise StringBuilder.Replace() (comme dans Xamarin) :
Temps total (5 exécutions) : 3646 ms, avec un total de 3830 ms pour la lecture du fichier.

Dot42, le code de Greg utilise String.Replace() (comme dans le code de Java et de Robert) :
Temps total (5 exécutions) : 3027 ms, avec un total de 3206 ms pour la lecture du fichier.

Dot42, Code Robert :
Temps total (5 exécutions) : 1781 ms, avec un total de lecture de fichier : 1999 ms

Xamarin :
Temps total (5 exécutions) : 1373 ms, avec un total de 1505 ms pour la lecture du fichier.

Java :
Temps total (5 exécutions) : 1841 ms, avec un total de 2044 ms pour la lecture du fichier.

ARM, Samsung Galaxy Note 2, économie d'énergie désactivée, Android 4.1.1

Dot42, le code de Greg utilise StringBuilder.Replace() (comme dans Xamarin) :
Temps total (5 exécutions) : 10875 ms, avec un total de 11280 ms pour la lecture du fichier.

Dot42, le code de Greg utilise String.Replace() (comme dans le code de Java et de Robert) :
Temps total (5 exécutions) : 9710 ms, avec un total de lecture de fichier : 10097 ms

Dot42, Code Robert :
Temps total (5 exécutions) : 6279 ms, avec un total de 6622 ms pour la lecture du fichier.

Xamarin :
Temps total (5 exécutions) : 6201 ms, avec un total de 6476 ms pour la lecture du fichier.

Java :
Temps total (5 exécutions) : 7141 ms, avec un total de 7479 ms pour la lecture du fichier.

Je pense toujours que Dot42 a un long chemin à parcourir. Le fait d'avoir des classes semblables à celles de Java (par exemple ArrayList) et une bonne performance avec elles, rendrait le portage de code de Java à C# légèrement plus facile. Cependant, c'est quelque chose que je ne ferais probablement pas souvent. Je préférerais utiliser du code C# existant (bibliothèques, etc.), qui utilisera des classes C# natives (par exemple List), et qui fonctionnera lentement avec le code actuel dot42, et très bien avec Xamarin.

Greg

5 votes

Mode DEBUG sur Nexus 7 4.2.2 avec quelques optimisations sur les chaînes de caractères et xamarin alpha 9 : Temps total : 3907 ms, avec un total de lecture de fichiers : 4016. Que signifie "5 runs" ?

0 votes

Mode Release sur la même plateforme : Temps total : 2192 ms, avec un total de lecture de fichiers : 2279

0 votes

Mais votre code peut être optimisé bien davantage.

65voto

iceone23 Points 302

Oui, la machine virtuelle Mono de Xamarin est plus impressionnante que la Dalvik de Google utilisée dans Android. Je l'ai testé avec les tablettes HTC Flyer et Acer Iconia Tab pour comparer le portage C# d'Android via Mono à Java Dalvik, et l'implémentation C# d'Android a bel et bien battu Dalvik basé sur Java.

4 votes

@PeterLawrey, veuillez consulter ma mise à jour de la question. J'ai l'intention de porter une partie de mon code Java réel en C# et d'effectuer des tests, puis de les poster ici - s'ils rouvrent ma question, car les vigiles de SO l'ont fermée presque immédiatement.

1 votes

@PeterLawrey - J'ai maintenant effectué mes tests et posté les résultats sur StackOverflow, mais dans la question elle-même, car elle reste toujours "verrouillée" et je ne peux pas poster de réponse. Si vous le pouvez, veuillez ajouter votre vote pour rouvrir la question. Les résultats sont intéressants, sur ARM Java gagne haut la main, sur Intel - le code C# dans Mono est beaucoup plus rapide.

9 votes

@gregko Il est intéressant de noter que vous voyez que le C# est émulé plus rapidement, mais que Java est plus rapide sur les vrais téléphones. Pour moi, il s'agit d'une distinction importante. Je ne m'inquiéterais pas de la performance de l'émulateur, en fait je suggérerais que vous voulez que l'émulateur soit aussi lent/rapide que la chose réelle. J'ai voté pour la réouverture.

45voto

I came across this interesting post

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

Android App Performance

iOS App Performance

J'espère que ces informations vous seront utiles.

35voto

Christopher Points 5252

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 ont dû être réécrits pour la version Android.

Nous avons découvert que les entrées/sorties dans Xamarin C# sont environ deux fois plus lentes que dans Java. Notre application est fortement liée aux E/S. Nous n'avons pas encore découvert la cause de ce phénomène, mais pour l'instant, nous supposons qu'il est dû au marshaling. Bien que nous essayions de rester à l'intérieur de la VM Mono la plupart du temps, nous ne savons pas comment Mono accède réellement au disque.

Il est également révélateur que notre code C# utilise SQLite.NET ( https://github.com/praeclarum/sqlite-net ). Des recherches identiques effectuées à l'aide du code SQLite.NET sont également deux fois plus lentes qu'avec le wrapper Java SQLite d'Android. Après avoir examiné le code source, il semble qu'il se lie directement à la dll C, donc je ne sais pas pourquoi il est si lent. Une possibilité est que le marshaling de chaînes de caractères de natif à Java est plus rapide sur Android que de natif à C# sur Xamarin.

1 votes

Cela a très probablement aussi à voir avec les "liens" dont Xamerin a besoin pour interagir avec le système. Chaque appel système par défaut va à une classe Java mais doit être délégué à la Mono VM, ce qui prend du temps. La même chose se produit également en sens inverse. J'ai expliqué cela un peu plus dans ma réponse : stackoverflow.com/a/46973819/1052697

34voto

Daniel Points 825

Voici un autre article de blog plus récent que je voudrais partager avec vous. . Il compare Xamarin au code natif et à Cordova sur IOs et Android.

En un mot, Xamarin est parfois plus performant que le code natif. Il a testé la taille de l'application, les temps de chargement, le chargement d'une liste depuis le service Azure et le calcul de nombres premiers.

Profitez-en !

Edit : J'ai mis à jour le lien mort et j'ai remarqué que il y a une partie 2

12voto

Burgito Points 61

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 appareils suivants :

Samsung Galaxy A7 : Version du système d'exploitation Android : 6.0 Unité centrale de traitement : Octa-core 1.9 GHz Cortex-A53 MÉMOIRE VIVE : 3 GO Résolution d'affichage : 1920×1080

iPhone 6s : Version iOS : 10.3.3 Unité centrale de traitement : Twister à double cœur de 1,84 GHz MÉMOIRE VIVE : 2 GO Résolution de l'écran : 1334×750

La comparaison se fait sur quelques caractéristiques communes, chacune ayant 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

Basic Hellow World performance comparison


API de repos

Ensemble de tests visant à mesurer le temps nécessaire à l'application pour envoyer une requête via l'API REST et recevoir la réponse en retour sans traitement supplémentaire des données, en utilisant l'API OpenWeatherMap.

Rest API performance comparison


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

Deux exécutions 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 manche :

JSON serialization first run

JSON deserialization first run

(Les opérations JSON de l'iOS natif tuent ce test, et Xamarin le rejoint dans le second).

JSON Serialization second run

JSON Deserialization second run


Opérations photo

Chargez d'abord 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 First Load Android

Image First Load 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: Retrieving all data from the database.

Avec des bases de données de 10 000 enregistrements. Toutes les opérations étaient traitées en interne sur les appareils.

SQLite Android performances

SQLite iOS performances


Xamarin Native (Xamarin.iOS/Xamarin.Android) se présentent comme d'assez bonnes alternatives au code natif, tandis que Xamarin.Forms semble lent dans de nombreux cas, mais il peut être une très bonne solution pour développer rapidement des applications vraiment 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 me donner les explications pour améliorer ma réponse, j'espère que cela vous aidera un peu :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X