Je suis tombé sur Xamarin qui prétend que leur implémentation Mono sur Android et leurs applications compilées en C # sont plus rapides que le code Java. Quelqu'un a-t-il effectué de véritables tests de performance sur du code Java et C # très similaire sur différentes plates-formes Android pour vérifier ces affirmations, pourrait-il publier le code et les résultats?
Publié le 18 juin 2013
Puisqu'il n'y avait pas de réponse et ne pouvait pas trouver de tels repères effectués par d'autres, j'ai décidé de faire mes propres tests. Malheureusement, ma question reste "verrouillée", je ne peux donc pas poster ceci comme réponse, seulement éditer la question. Veuillez voter pour rouvrir 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 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é d'apprendre 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 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: Grand total time (5 runs): 12361 ms, avec lecture du fichier total: 13304 ms
C #: Temps total total (5 exécutions): 17504 ms, avec total de lecture de fichiers: 17956 ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM
Java: Grand total time (5 runs): 8947 ms, avec total de lecture de fichiers: 9186 ms
C #: Temps total total (5 exécutions): 9884 ms, avec total de lecture de fichiers: 10247 ms
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM
Java: Grand total time (5 runs): 9742 ms, avec total de lecture de fichiers: 10111 ms
C #: Temps total total (5 passages): 10459 ms, avec total de lecture de fichiers: 10696 ms
Émulateur - Intel (Android 4.2, API 17)
Java: Grand total time (5 runs): 2699 ms, avec lecture du fichier total: 3127 ms
C #: Temps total total (5 exécutions): 2049 ms, avec total de lecture de fichiers: 2182 ms
Émulateur - Intel (Android 2.3.7, API 10)
Java: Grand total time (5 runs): 2992 ms, avec lecture du fichier total: 3591 ms
C #: Temps total total (5 exécutions): 2049 ms, avec lecture totale du fichier: 2257 ms
Emulator - Arm (Android 4.0.4, API 15)
Java: Grand total time (5 runs): 41751 ms, avec lecture du fichier total: 43866 ms
C #: Temps total total (5 passages): 44136 ms, avec total de lecture de fichiers: 45109 ms
Brève discussion
Mon code de test contient principalement l'analyse de texte, le remplacement et les recherches Regex, peut-être pour un autre code (par exemple plus d'opérations numériques) les résultats seraient différents. Sur tous les appareils dotés de processeurs ARM, Java s'est comporté mieux que le code Xamarin C #. La plus grande différence était sous Android 2.3, où le code C # s'exécute à environ. 70% de la vitesse Java.
Sur l'émulateur Intel (avec la technologie Intel HAX, l'émulateur s'exécute en mode virt rapide), le code Xamarin C # exécute mon exemple de code beaucoup plus rapidement que Java - environ 1,35 fois plus rapidement. Peut-être que le code et les bibliothèques des machines virtuelles mono sont bien mieux optimisés sur Intel que sur ARM?
Modifier le 8 juillet 2013
Je viens d'installer l'émulateur Genymotion Android, qui s'exécute dans Oracle VirtualBox, et encore celui-ci utilise un processeur Intel natif, pas un processeur ARM émulant. Comme avec l'émulateur Intel HAX, C # s'exécute à nouveau ici beaucoup plus rapidement. Voici mes résultats:
Émulateur Genymotion - Intel (Android 4.1.1, API 16)
Java: Grand total time (5 runs): 2069 ms, avec lecture du fichier total: 2248 ms
C #: Temps total total (5 exécutions): 1543 ms, avec total de lecture de fichiers: 1642 ms
J'ai ensuite remarqué qu'il y avait une mise à jour de la version 4.7.11 de Xamarin.Android beta, avec des notes de publication mentionnant également certains changements dans l'exécution Mono. Décidé de tester rapidement certains appareils ARM, et grande surprise - les numéros C # ont été améliorés:
BN Nook XD +, ARM (Android 4.0)
Java: Grand total time (5 runs): 8103 ms, avec lecture du fichier total: 8569 ms
C #: Temps total total (5 exécutions): 7951 ms, avec un total de lecture de fichiers: 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: Grand total time (5 runs): 9675 ms, avec lecture du fichier total: 10028 ms
C #: Temps total total (5 exécutions): 9911 ms, avec total de lecture de fichiers: 10104 ms
Ici, C # semble être légèrement plus lent, mais ces chiffres m'ont donné une pause: pourquoi le temps est plus long que sur Nook HD +, même si Note 2 a un processeur plus rapide? La réponse: le mode d'économie d'énergie. Sur Nook, il était désactivé, sur 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: Grand total time (5 runs): 7153 ms, avec lecture du fichier total: 7459 ms
C #: Temps total total (5 exécutions): 6906 ms, avec un total de lecture de fichiers: 7070 ms
Maintenant, étonnamment, C # est également légèrement plus rapide que Java sur le processeur ARM. Grande amélioration!
Modifier 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 en C #, en particulier que je devais l'améliorer (et donc le rendre encore plus lent). 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 natif par rapport à Java sur mon Galaxy Note 2, avec le mode d'économie d'énergie désactivé:
Java: Grand total time (5 runs): 3292 ms, avec lecture du fichier total: 3454 ms
Pouce natif: Durée totale totale (5 exécutions): 537 ms, avec lecture totale du fichier: 657 ms
Bras natif: Grand total time (5 runs): 458 ms, avec lecture du fichier total: 587 ms
On dirait que 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, j'ai donc dû écrire mes propres routines spécialisées à la recherche de sauts de paragraphes ou de balises html. Mes premiers tests 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 pointeurs char * ou wchar *, je me suis immédiatement senti 20 ans plus jeune! :)
Modifier le 15 juillet 2013
(Veuillez 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 # sur 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 3 fois (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, j'ai donc 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 cependant pas être un gros problème. Dot42 se compile en code Dalvik (DEX), donc il coopère avec Java sur Android nativement, n'a pas besoin d'une interopérabilité coûteuse de C # vers Java comme Xamarin.
À titre de comparaison, je lance également le test sur les appareils ARM - ici, le code Dot42 est "seulement" 2x plus lent que Xamarin C #. Voici mes résultats:
HTC Nexus One Android 2.3.7 (ARM)
Java: Grand total time (5 runs): 12187 ms, avec lecture du fichier total: 13200 ms
Xamarin C #: Temps total total (5 exécutions): 13935 ms, avec un total de lecture de fichiers: 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: Grand total time (5 runs): 6895 ms, avec lecture du fichier total: 7275 ms
Xamarin C #: Temps total total (5 exécutions): 6466 ms, avec un total de lecture de fichiers: 6720 ms
Dot42 C #: Temps total total (5 passages): 11185 ms, avec total de lecture de fichiers: 11843 ms
Émulateur Intel, Android 4.2 (x86)
Java: Grand total time (5 runs): 2389 ms, avec lecture du fichier total: 2770 ms
Xamarin C #: Temps total total (5 exécutions): 1748 ms, avec total de lecture de fichiers: 1933 ms
Dot42 C #: Temps total total (5 exécutions): 5150 ms, avec un total de lecture de fichiers: 5459 ms
Pour moi, il était également intéressant de noter que Xamarin C # est légèrement plus rapide que Java sur un appareil ARM plus récent et légèrement plus lent sur l'ancien Nexus One. Si quelqu'un souhaite également exécuter 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 avec 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 également 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 - de meilleurs résultats pour dot42
Testé de nouveau Dot42 avec le port de Robert (des fabricants de dot42) de mon code Java en C #. Dans mon port C # fait initialement pour Xamarin, j'ai remplacé certaines classes Java natives, comme ListArray, par une classe List native en C #, etc. ces endroits, ce qui profite à Dot42, je suppose parce qu'il fonctionne dans Dalvik VM, comme Java, et non en 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, Code de Greg utilisant StringBuilder.Replace () (comme dans Xamarin):
Temps total général (5 exécutions): 3646 ms, avec un total de lecture de fichiers: 3830 msDot42, le code de Greg utilisant String.Replace () (comme dans le code Java et Robert):
Temps total général (5 exécutions): 3027 ms, avec lecture totale du fichier: 3206 msDot42, Robert's Code:
Grand total time (5 runs): 1781 ms, avec lecture totale du fichier: 1999 msXamarin:
Grand total time (5 runs): 1373 ms, avec un total de lecture de fichiers: 1505 msJava:
Grand total time (5 runs): 1841 ms, avec lecture du fichier total: 2044 msARM, Samsung Galaxy Note 2, économie d'énergie, Android 4.1.1
Dot42, Greg's Code utilisant StringBuilder.Replace () (comme dans Xamarin):
Temps total total (5 exécutions): 10875 ms, avec un total de lecture de fichiers: 11280 msDot42, Code de Greg utilisant String.Replace () (comme dans le code Java et Robert):
Temps total général (5 exécutions): 9710 ms, avec total de lecture de fichiers: 10097 msDot42, Robert's Code:
Grand total time (5 runs): 6279 ms, avec total de lecture de fichiers: 6622 msXamarin:
Grand total time (5 runs): 6201 ms, avec un total de lecture de fichiers: 6476 msJava:
Grand total time (5 runs): 7141 ms, avec lecture du fichier total: 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 elles rendrait le portage de code de Java vers C # légèrement plus facile. Cependant, c'est quelque chose que je ne ferais probablement pas beaucoup. Je préférerais utiliser le code C # existant (bibliothèques, etc.), qui utilisera des classes C # natives (par exemple, List), et cela fonctionnerait lentement avec le code dot42 actuel, et très bien avec Xamarin.
Greg
Réponses:
Oui, la machine virtuelle Mono de Xamarin est plus impressionnante que Dalvik de Google utilisé dans Android. Je l'ai testé avec les tablettes HTC Flyer et Acer Iconia Tab pour comparer le port C # d'Android via Mono par rapport à Java Dalvik, avec l'implémentation C # d'Android bien et vraiment contre le Dalvik basé sur Java.
la source
https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz
J'espère que cette information vous aidera.
la source
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 2x plus lentes que Java. Notre application est fortement liée aux E / S. Nous n'avons pas encore découvert la cause de cela, mais pour le moment nous supposons que cela est dû au marshaling. Bien que nous essayions de rester à l'intérieur de la machine virtuelle 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 ). Les récupérations identiques à l'aide du code SQLite.NET sont également 2 fois plus lentes qu'à l'aide du wrapper Java SQLite d'Android. Après avoir regardé le code source, il semble se lier directement au C .dll, donc je ne sais pas pourquoi il est tellement plus lent. Une possibilité est que le marshaling des chaînes natives vers Java soit plus rapide sur Android que natif vers C # sur Xamarin.
la source
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 les IO et Android.
En un mot, 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 du nombre premier.
Prendre plaisir!
Edit: j'ai mis à jour le lien mort et j'ai remarqué qu'il y a une partie 2
la source
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 Android OS: 6.0 Unité centrale: Octa-core 1.9 GHz Cortex-A53 RAM: 3 Go Résolution d'affichage: 1920 × 1080
iPhone 6s : version iOS: 10.3.3 Unité centrale: Dual-core 1,84 GHz RAM Twister: 2 Go Résolution d'affichage: 1334 × 750
La comparaison est faite sur quelques fonctionnalités communes, chacune avec sa propre application:
Chaque test est répété plusieurs fois, les graphiques montrent les résultats moyens.
Bonjour le monde
API Rest
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.
Tests d' opérations JSON réalisés à l'aide du framework Newtonsoft Json.net pour sérialiser et désérialiser des objets 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 exécutions sont effectuées, une première à partir de zéro et une seconde avec les informations et les opérations mises en cache
Première exécution :
(Les opérations JSON iOS natives tuent ce test btw, et Xamarin le rejoint dans le second)
Opérations photo
Premier chargement d'images avec trois résolutions différentes:
Quelque chose ne semblait pas sûr 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:
Avec des bases de données contenant 10 000 enregistrements. Toutes les opérations ont été traitées en interne sur les appareils.
Xamarin Native (Xamarin.iOS / Xamarin.Android) se présente comme une alternative plutôt bonne au code natif, tandis 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 aide un peu :)
la source
Performance
Les performances sont un mot vague si vous ne définissez pas ce que vous entendez par performances, s'il s'agit de performances de calcul simples, Xamarin peut être plus rapide que Java selon la nature du calcul.
Android est livré nativement avec des formulaires multipe pour exécuter du code dans:
Il est assez évident que lors de l'exécution de 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 CPU.
Mais d'un autre côté, si vous voulez mesurer les performances d'utilisation réelles, Java est plus rapide que Xamarin.
Xamarin et pourquoi il peut être plus lent
Lorsque vous comparez Xamarin avec de vieilles applications Java simples, 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 vers et depuis le runtime Xamarin à l'aide de soi-disant liaisons.
Il existe différents types de liaisons qu'il est important de connaître:
Les liaisons sont en termes de performances très très coûteuses. L'appel d'une méthode C ++ à partir de Java ajoute une énorme surcharge de temps d'appel, appeler une méthode C ++ à partir de C ++ est beaucoup plus rapide.
Mais non seulement les appels JNI sont coûteux, tout comme les appels vers et depuis MCW et ACW. Les applications Xamarin du monde réel effectuent de nombreux appels à l'aide de liaisons et, à cause de cela, l'utilisation réelle d'une application Xamarin peut être (et sera en général) plus lente qu'une ancienne application Java. Cependant, selon la façon dont l'application Xamarin a été conçue, il est très probable que l'utilisateur ne remarquera même pas la différence.
TLDR / Conclusion: Xamarin doit utiliser toutes les liaisons de tri, qui sont coûteuses en temps.
la source
Ce sont des tests assez anciens mais pourraient être pertinents: https://github.com/EgorBo/Xamarin.Android-vs-Java
Test arithmétique
Collections, génériques, types de valeur personnalisés
Travailler avec des chaînes
UPD: nouvelles données avec Google Pixel 2 (merci yousha-aleayoub )
la source