web-dev-qa-db-fra.com

Quelqu'un a-t-il des points de repère (code et résultats) comparant les performances de Android applications écrites en Xamarin C # et Java?

Je suis tombé sur Xamarin qui affirme que son implémentation Mono sur Android et ses applications compilées en C # sont plus rapides que le code Java. Quelqu'un at-il effectué des tests de performances sur des Java et des codes 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

Puisqu'il n'y avait pas de réponse et ne pouvait pas trouver de tels repères faits par d'autres, décidé de faire mes propres tests. Malheureusement, ma question reste "verrouillée" et je ne peux donc pas poster ceci comme réponse, mais seulement éditer la question. S'il vous plaît voter pour ré-ouvrir 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 tester et compiler les packages APK 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, j'aimerais aussi connaître les résultats.

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 testé 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 la durée totale pour 3 périphériques différents et un émulateur est affichée ci-dessous. J'ai testé uniquement les versions "Release", sans le débogage activé.

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

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

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

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

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

C #: Temps total total (5 analyses): 9884 ms, avec la lecture totale du fichier: 10247 ms

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

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

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

Émulateur - Intel (Android 4.2, API 17)

Java: Temps total total (5 exécutions): 2699 ms, total de lecture de fichier: 3127 ms

C #: Temps total total (5 exécutions): 2049 ms, total de lecture de fichier: 2182 ms

Émulateur - Intel (Android 2.3.7, API 10)

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

C #: Temps total total (5 analyses): 2049 ms, total de lecture de fichier: 2257 ms

Emulator - Arm (Android 4.0.4, API 15)

Java: Temps total total (5 exécutions): 41751 ms, total de lecture de fichier: 43866 ms

C #: Temps total total (5 analyses): 44136 ms, total de lecture de fichier: 45109 ms

Brève discussion

Mon code de test contient principalement des recherches d’analyse, de remplacement et d’analyse de texte. Peut-être que pour un autre code (opérations plus numériques, par exemple), les résultats seraient différents. Sur tous les périphériques dotés de processeurs ARM, Java a obtenu de meilleurs résultats que le code Xamarin C #. La plus grande différence était sous Android 2.3, où le code C # fonctionnait à env. 70% de Java vitesse.

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

Edit du 8 juillet 2013

Je viens d'installer l'émulateur Genymotion Android, qui s'exécute dans Oracle VirtualBox, qui utilise à nouveau un processeur Intel natif, sans émulation de processeur ARM. Comme avec l'émulateur Intel HAX, C # s'exécute ici beaucoup plus rapidement. Voici mes résultats:

Emulateur Genymotion - Intel (Android 4.1.1, API 16)

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

C #: Temps total total (5 analyses): 1543 ms, total de lecture de fichier: 1642 ms

J'ai ensuite remarqué qu'il y avait une mise à jour de Xamarin.Android beta, version 4.7.11, avec des notes de publication mentionnant également certaines modifications apportées à l'exécution de Mono. Décidé de tester rapidement certains périphériques ARM et une grande surprise: les numéros C # sont améliorés:

BN Nook XD +, ARM (Android 4.0)

Java: Temps total total (5 exécutions): 8103 ms, total de lecture de fichier: 8569 ms

C #: Temps total total (5 exécutions): 7951 ms, total de lecture de 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: Temps total total (5 exécutions): 9675 ms, total de lecture de fichier: 10028 ms

C #: Temps total total (5 analyses): 9911 ms, total de lecture de fichier: 10104 ms

Ici, C # ne semble être qu'un peu plus lent, mais ces chiffres m'ont fait une pause: pourquoi le temps est-il plus long que sur Nook HD +, alors que Note 2 a un processeur plus rapide? La réponse: le mode d'économie d'énergie. Sur Nook, il a été désactivé, sur Note 2 - activé. Décidé de tester avec le mode d'économie d'énergie désactivé (comme avec 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 total (5 exécutions): 7153 ms, total de lecture de fichier: 7459 ms

C #: Temps total total (5 exécutions): 6906 ms, total de lecture de fichier: 7070 ms

De manière surprenante, C # est légèrement plus rapide que Java sur le processeur ARM. Grande amélioration!

Edit 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 en C #, en particulier du fait que j’ai besoin de l’améliorer (et donc de le ralentir encore plus). . 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 de la vitesse native par rapport à Java sur mon Galaxy Note 2, avec le mode d'économie d'énergie désactivé:

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

Pouce native: Temps total total (5 analyses): 537 ms, avec la lecture totale du fichier: 657 ms

Bras natif: Temps total total (5 analyses): 458 ms, total de lecture de fichier: 587 ms

Il semble que pour mon test particulier, le code natif soit 6 à 7 fois plus rapide que Java. Mise en garde: ne pouvait pas utiliser la classe std :: regex sur Android, donc je devais écrire mes propres routines spécialisées à la recherche de sauts de paragraphe ou de balises html. Mes tests initiaux du même code sur un PC utilisant regex étaient environ 4 à 5 fois plus rapides que Java.

Phew! Réveillant la mémoire brute avec des indicateurs char * ou wchar *, je me suis immédiatement senti 20 ans plus jeune! :)

Editer le 15 juillet 2013

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

Avec quelques difficultés, j'ai réussi à 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 plus lent que Xamarin C # (version 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. J'ai donc utilisé la classe Java.Util.Regex à la place et Java.Util.Regex.Pattern.Split (). , donc à cet endroit particulier dans le code, il y a cette petite différence. Ne devrait pas être un gros problème cependant. Dot42 compile en code Dalvik (DEX), de sorte qu'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.

À titre de comparaison, j’effectue également le test sur ARM appareils - ici le code Dot42 n’est "que" 2x plus lent que Xamarin C #. Voici mes résultats:

HTC Nexus One Android 2.3.7 (ARM)

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

Xamarin C #: Temps total total (5 analyses): 13935 ms, avec la lecture totale du fichier: 14465 ms

Point42 C #: Temps total total (5 exécutions): 26000 ms, total de lecture de fichier: 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: Temps total total (5 exécutions): 6895 ms, total de lecture de fichier: 7275 ms

Xamarin C #: Temps total total (5 analyses): 6466 ms, avec la lecture totale du fichier: 6720 ms

Point42 C #: Temps total total (5 analyses): 11185 ms, avec la lecture totale du fichier: 11843 ms

Emulateur Intel, Android 4.2 (x86)

Java: Temps total total (5 exécutions): 2389 ms, total de lecture de fichier: 2770 ms

Xamarin C #: Temps total total (5 analyses): 1748 ms, avec la lecture totale du fichier: 1933 ms

Point42 C #: Temps total total (5 analyses): 5150 ms, total de lecture de 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 nouveau périphérique ARM et légèrement plus lent sur l'ancien Nexus One. Si vous souhaitez également exécuter ces tests, merci de me le signaler et de mettre à jour les sources sur GitHub. Il serait particulièrement intéressant de voir les résultats d’un vrai périphérique Android doté d’un processeur Intel.

Mise à jour 26/07/2013

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

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

Re-testé Dot42 avec le portage de Robert (de dot42 makers) de mon code Java en C #. Dans mon portage C # créé initialement pour Xamarin, j'ai remplacé certaines classes Java natives, telles que ListArray, par une classe List native de C #, etc. Robert n'avait pas mon code source Dot42; il l'a donc porté à nouveau à partir de Java et utilisait les classes d'origine Java dans de tels endroits, ce qui profite à Dot42, car il fonctionne sous Dalvik VM, comme Java, et non sous Mono, comme Xamarin. Maintenant, les résultats de Dot42 sont bien meilleurs. Voici un journal de mes tests:

30/07/2013 - Tests Dot42 avec plusieurs classes Java dans Dot42 C #

Emulateur Intel, Android 4.2

Dot42, le code de Greg utilisant StringBuilder.Replace () (comme dans Xamarin):
Temps total total (5 exécutions): 3646 ms, total de lecture de fichier: 3830 ms

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

Dot42, le code de Robert:
Temps total (5 exécutions): 1781 ms, total des lectures de fichier: 1999 ms

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

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

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

Dot42, le code de Greg utilisant StringBuilder.Replace () (comme dans Xamarin):
Temps total total (5 exécutions): 10875 ms, total de lecture de fichier: 11280 ms

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

Dot42, le code de Robert:
Temps total total (5 exécutions): 6279 ms, total de lecture de fichier: 6622 ms

Xamarin:
Temps total total (5 exécutions): 6201 ms, total de lecture de fichier: 6476 ms

Java:
Temps total total (5 exécutions): 7141 ms, total de lecture de fichier: 7479 ms

Je pense toujours que Dot42 a un long chemin à parcourir. Avoir des classes de type Java (par exemple, ArrayList) et de bonnes performances avec celles-ci rendrait le portage du code de Java vers C # légèrement plus facile. 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 des classes C # natives (par exemple, List), et qui fonctionnerait lentement avec le code dot42 actuel et très bien avec Xamarin.

Greg

530
gregko

Ouais, 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 port C # de Android à Mono par rapport à Java Dalvik, avec l'implémentation C # de Android bien et vraiment dominer le Dalvik basé sur Java.

62
klvtsov
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 cette information aide.

42

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.

Ce que nous avons découvert, c’est que les E/S dans Xamarin C # sont environ deux fois plus lentes que Java. Notre application est fortement liée I/O. Nous n'avons pas encore découvert la cause de ceci, mais pour le moment nous supposons que cela est dû au marshaling. Bien que nous essayions de rester à l'intérieur du Mono VM 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 ). 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 Cdll, je ne sais donc pas pourquoi il est tellement plus lent. Une possibilité est que le marshaling des chaînes de natif à Java soit plus rapide sur Android que natif à C # sur Xamarin.

34
Christopher

Ceci est un autre article de blog plus mis à jour que je voudrais partager avec vous . Il compare Xamarin au code natif et Cordova sur IO 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 à partir du service Azure et le calcul du nombre premier.

Prendre plaisir!

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

34
Daniel

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

Samsung Galaxy A7 : Android version du système d'exploitation: 6.0 Unité centrale de traitement: Octa-core 1.9 GHz Cortex-A53 RAM: 3 Go résolution: 1920 × 1080

iPhone 6s : version iOS: 10.3.3 Unité centrale de traitement: double cœur Twister RAM 1.84 GHz: 2 Go Résolution d'affichage: 1334 × 750

La comparaison repose 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 tout le monde

Basic Hellow World performance comparison


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 de données supplémentaire, à l'aide de l'API OpenWeatherMap.

Rest API performance comparison


Opérations JSON Tests effectués à l'aide du framework Newtonsoft Json.net pour sérialiser et désérialiser des objets JSON dans toutes les applications Xamarin. La sérialisation et la désérialisation natives Android ont été 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 en cache

Première exécution :

JSON serialization first run

JSON deserialization first run

(Les opérations JSON natives pour iOS éliminent ce test, et Xamarin le rejoint à la seconde)

JSON Serialization second run

JSON Deserialization second run


Opérations photo

Commencez par charger 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 à propos des 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 ayant 10 000 enregistrements. Toutes les opérations ont été traitées en interne sur les appareils.

SQLite Android performances

SQLite iOS performances


Xamarin Native (Xamarin.iOS/Xamarin.Android) se présente comme une assez bonne alternative au code natif, alors que Xamarin.Forms semble lent dans de nombreux cas, mais il 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-native-applications/

Merci de me donner les explications pour améliorer ma réponse, espérons que cela aide un peu :)

10
Burgito

Performance

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

Android nativly est livré avec plusieurs formulaires pour exécuter du code dans:

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

Il est bien é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 bat jamais un langage qui s'exécute directement sur le processeur.

Par contre, si vous souhaitez mesurer les performances d'utilisation dans la vie réelle Java, il est prévu que ce sera plus rapide que Xamarin.

Xamarin et pourquoi cela peut être plus lent

Lorsque vous comparez Xamarin avec des applications simples Java, les performances peuvent très bien être plus rapides pour Xamarin, car elles peuvent être plus lentes.

Dans un exemple concret, les applications Xamarin sont très probablement plus lentes que les applications Java car de nombreux appels Android/Java (système) doivent être délégués à l'exécution et à l'exécution de Xamarin à l'aide de liaisons.

Il est important de connaître différents types de liaisons:

  • JNI (interface native Java): La liaison utilisée dans de nombreux Android applications servant d'interface entre Java code ( SDK) et le code C++ natif (NDK).
  • MCW (Managed Callable Wrappers): Une liaison disponible dans Xamarin pour l’interface du code C # géré vers Java code (exécution sous Android). -temps).
  • ACW (Android Callable Wrappers): Une liaison disponible dans Xamarin pour une interface allant de Java code (exécution Android) à 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 fixations sont très coûteuses en termes de performances. L'appel d'une méthode C++ à partir de Java ajoute une surcharge de temps en temps d'appel. L'appel d'une méthode C++ à partir de C++ est beaucoup plus rapide.

Quelqu'un a fait un test de performances pour calculer combien Java opérations en moyenne un appel JNI coûte: Quel est le surcoût quantitatif lié à la réalisation d'un appel JNI?

Mais les appels JNI ne sont pas les seuls à coûter cher, il en va de même pour les appels de MCW et ACW. Les applications Xamarin dans le monde réel effectuent de nombreux appels à l'aide de liaisons et, en raison de ce contexte, l'utilisation d'une application Xamarin peut être (et sera en général) plus lente qu'une application ancienne 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 les liaisons de tri qui prennent beaucoup de temps.

Outre les liaisons, de nombreux autres facteurs entrent en ligne de compte lorsque l'on parle de performances dans le monde réel, par exemple: la taille du binaire, le chargement de l'application en mémoire, les opérations d'E/S, etc. Vous trouverez un article de blog qui étudie certaines de ces choses ici: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin -xamarin-formes

7
Rolf ツ

Ce sont des tests assez anciens mais qui pourraient être pertinents: https://github.com/EgorBo/Xamarin.Android-vs-Java

Test arithmétique

enter image description here

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

enter image description here

Utilisation de chaînes de caractères

enter image description here

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

Pixel 2 tests

2
Denis Gordin