Ich bin auf Xamarin-Behauptungen gestoßen, dass ihre Mono-Implementierung auf Android und ihre C # -kompilierten Apps schneller sind als Java-Code. Hat jemand tatsächliche Benchmarks für sehr ähnlichen Java- und C # -Code auf verschiedenen Android-Plattformen durchgeführt, um solche Behauptungen zu überprüfen, konnte er den Code und die Ergebnisse veröffentlichen?
Hinzugefügt am 18. Juni 2013
Da es keine Antwort gab und solche von anderen durchgeführten Benchmarks nicht finden konnten, entschied ich mich, meine eigenen Tests durchzuführen. Leider bleibt meine Frage "gesperrt", so dass ich dies nicht als Antwort posten kann, sondern nur die Frage bearbeiten kann. Bitte stimmen Sie ab, um diese Frage erneut zu öffnen. Für C # habe ich Xamarin.Android Ver verwendet. 4.7.09001 (Beta). Der Quellcode, alle Daten, die ich zum Testen und Kompilieren von APK-Paketen verwendet habe, befinden sich auf GitHub:
Java: https://github.com/gregko/TtsSetup_Java
C #: https://github.com/gregko/TtsSetup_C_sharp
Wenn jemand meine Tests auf anderen Geräten oder Emulatoren wiederholen möchte, wäre ich interessiert, auch die Ergebnisse zu erfahren.
Ergebnisse meiner Tests
Ich habe meine Klasse zum Extrahieren von Sätzen auf C # portiert (aus meiner @ Voice Aloud Reader-App) und einige Tests mit 10 HTML-Dateien in Englisch, Russisch, Französisch, Polnisch und Tschechisch durchgeführt. Jeder Lauf wurde 5 Mal für alle 10 Dateien durchgeführt. Die Gesamtzeit für 3 verschiedene Geräte und einen Emulator ist unten angegeben. Ich habe nur "Release" Builds getestet, ohne dass das Debuggen aktiviert war.
HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM
Java: Gesamtsumme der Zeit (5 Läufe): 12361 ms, mit einer Gesamtlesezeit von 13304 ms
C #: Gesamtsumme der Zeit (5 Läufe): 17504 ms, mit einer Gesamtlesezeit von 17956 ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM
Java: Gesamtsumme (5 Läufe): 8947 ms, mit einer Lesesumme von 9186 ms
C #: Gesamtsumme der Zeit (5 Läufe): 9884 ms, mit einer Gesamtlesezeit von 10247 ms
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM
Java: Gesamtsumme (5 Läufe): 9742 ms, mit einer Lesesumme von 10111 ms
C #: Gesamtsumme (5 Läufe): 10459 ms, mit einer Lesesumme von 10696 ms
Emulator - Intel (Android 4.2, API 17)
Java: Gesamtsumme der Zeit (5 Läufe): 2699 ms, mit einer Gesamtlesezeit von 3127 ms
C #: Gesamtsumme der Zeit (5 Läufe): 2049 ms, mit einer Gesamtlesezeit von 2182 ms
Emulator - Intel (Android 2.3.7, API 10)
Java: Gesamtsumme der Zeit (5 Läufe): 2992 ms, mit einer Gesamtlesezeit von 3591 ms
C #: Gesamtsumme der Zeit (5 Läufe): 2049 ms, mit einer Gesamtlesezeit von 2257 ms
Emulator - Arm (Android 4.0.4, API 15)
Java: Gesamtsumme der Zeit (5 Läufe): 41751 ms, mit einer Gesamtlesezeit von 43866 ms
C #: Gesamtsumme der Zeit (5 Läufe): 44136 ms, mit einer Gesamtlesezeit von 45109 ms
Kurze Diskussion
Mein Testcode enthält hauptsächlich Textanalyse, Ersetzen und Regex-Suche. Möglicherweise sind die Ergebnisse für anderen Code (z. B. mehr numerische Operationen) anders. Auf allen Geräten mit ARM-Prozessoren schnitt Java besser ab als Xamarin C # -Code. Der größte Unterschied bestand unter Android 2.3, wo C # -Code mit ca. 70% der Java-Geschwindigkeit.
Auf dem Intel-Emulator (mit Intel HAX-Technologie läuft der Emulator im Fast-Virt-Modus) führt Xamarin C # -Code meinen Beispielcode viel schneller aus als Java - ungefähr 1,35-mal schneller. Vielleicht sind der Code und die Bibliotheken der virtuellen Mono-Maschine unter Intel viel besser optimiert als unter ARM?
Bearbeiten 8. Juli 2013
Ich habe gerade den Genymotion Android-Emulator installiert, der in Oracle VirtualBox ausgeführt wird, und auch dieser verwendet einen nativen Intel-Prozessor, der keinen ARM-Prozessor emuliert. Wie beim Intel HAX Emulator läuft auch hier C # viel schneller. Hier sind meine Ergebnisse:
Genymotion-Emulator - Intel (Android 4.1.1, API 16)
Java: Gesamtsumme (5 Läufe): 2069 ms, mit einer Lesesumme von 2248 ms
C #: Gesamtsumme der Zeit (5 Läufe): 1543 ms, mit einer Lesesumme von 1642 ms
Ich bemerkte dann, dass es ein Update für Xamarin.Android Beta, Version 4.7.11 gab, mit Versionshinweisen, in denen auch einige Änderungen in der Mono-Laufzeit erwähnt wurden. Beschlossen, einige ARM-Geräte schnell zu testen, und große Überraschung - C # -Nummern verbessert:
BN Nook XD +, ARM (Android 4.0)
Java: Gesamtsumme (5 Läufe): 8103 ms, mit einer Lesesumme von 8569 ms
C #: Gesamtsumme (5 Läufe): 7951 ms, mit einer Lesesumme von 8161 ms
Beeindruckend! C # ist jetzt besser als Java? Beschlossen, den Test auf meinem Galaxy Note 2 zu wiederholen:
Samsung Galaxy Note 2 - ARM (Android 4.1.1)
Java: Gesamtsumme (5 Läufe): 9675 ms, mit einer Lesesumme von 10028 ms
C #: Gesamtsumme (5 Läufe): 9911 ms, mit einer Lesesumme von 10104 ms
Hier scheint C # nur geringfügig langsamer zu sein, aber diese Zahlen gaben mir eine Pause: Warum ist die Zeit länger als bei Nook HD +, obwohl Note 2 einen schnelleren Prozessor hat? Die Antwort: Energiesparmodus. In Nook war es deaktiviert, in Note 2 aktiviert. Beschlossen, mit deaktiviertem Energiesparmodus zu testen (wie aktiviert aktiviert, begrenzt es auch die Prozessorgeschwindigkeit):
Samsung Galaxy Note 2 - ARM (Android 4.1.1), Energiesparen deaktiviert
Java: Gesamtsumme der Zeit (5 Läufe): 7153 ms, mit einer Gesamtlesezeit von 7459 ms
C #: Gesamtsumme (5 Läufe): 6906 ms, mit einer Lesesumme von 7070 ms
Jetzt ist C # überraschenderweise auch auf dem ARM-Prozessor etwas schneller als Java. Großer Fortschritt!
Bearbeiten 12. Juli 2013
Wir alle wissen, dass nichts besser ist als nativer Code, und ich war mit der Leistung meines Satzteilers in Java oder C # nicht zufrieden, insbesondere, dass ich ihn verbessern (und damit noch langsamer machen) muss. Beschlossen, es in C ++ neu zu schreiben. Hier ist ein kleiner (dh aus anderen Gründen kleinerer Satz von Dateien als bei früheren Tests) Vergleich der Geschwindigkeit von nativem mit Java auf meinem Galaxy Note 2 bei deaktiviertem Energiesparmodus:
Java: Gesamte Gesamtzeit (5 Läufe): 3292 ms, mit einer Gesamtlesezeit von 3454 ms
Native Daumen: Gesamtsumme der Zeit (5 Läufe): 537 ms, mit einer Gesamtlesezeit von 657 ms
Native Arm: Gesamte Gesamtzeit (5 Läufe): 458 ms, mit einer Gesamtlesezeit von 587 ms
Sieht für meinen speziellen Test so aus, als wäre der native Code 6 bis 7 Mal schneller als Java. Vorsichtsmaßnahme: Die Klasse std :: regex konnte unter Android nicht verwendet werden. Daher musste ich meine eigenen speziellen Routinen schreiben, um nach Absatzumbrüchen oder HTML-Tags zu suchen. Meine ersten Tests desselben Codes auf einem PC mit Regex waren etwa vier- bis fünfmal schneller als bei Java.
Puh! Als ich wieder mit char * oder wchar * Zeigern die rohe Erinnerung weckte, fühlte ich mich sofort 20 Jahre jünger! :) :)
Bearbeiten 15. Juli 2013
(Weitere Informationen zu besseren Ergebnissen mit Dot42 finden Sie weiter unten mit den Änderungen vom 30.07.2013.)
Mit einigen Schwierigkeiten gelang es mir, meine C # -Tests auf Dot42 (Version 1.0.1.71 Beta) zu portieren, eine andere C # -Plattform für Android. Vorläufige Ergebnisse zeigen, dass Dot42-Code auf einem Intel Android-Emulator etwa dreimal (dreimal) langsamer ist als Xamarin C # (Version 4.7.11). Ein Problem ist, dass die System.Text.RegularExpressions-Klasse in Dot42 nicht über die Split () -Funktion verfügt, die ich in Xamarin-Tests verwendet habe. Daher habe ich stattdessen die Java.Util.Regex-Klasse und Java.Util.Regex.Pattern.Split () verwendet. An dieser Stelle im Code gibt es also diesen kleinen Unterschied. Sollte aber kein großes Problem sein. Dot42 kompiliert zu Dalvik (DEX) -Code, arbeitet also nativ mit Java auf Android zusammen und benötigt kein teures Interop von C # nach Java wie Xamarin.
Zum Vergleich führe ich den Test auch auf ARM-Geräten durch - hier ist der Dot42-Code "nur" 2x langsamer als Xamarin C #. Hier sind meine Ergebnisse:
HTC Nexus One Android 2.3.7 (ARM)
Java: Gesamtsumme (5 Läufe): 12187 ms, mit einer Lesesumme von 13200 ms
Xamarin C #: Gesamtsumme (5 Läufe): 13935 ms, mit einer Lesesumme von 14465 ms
Dot42 C #: Gesamtsumme (5 Läufe): 26000 ms, mit einer Lesesumme von 27168 ms
Samsung Galaxy Note 2, Android 4.1.1 (ARM)
Java: Gesamtsumme (5 Läufe): 6895 ms, mit einer Lesesumme von 7275 ms
Xamarin C #: Gesamtsumme (5 Läufe): 6466 ms, mit einer Gesamtlesezeit von 6720 ms
Dot42 C #: Gesamtsumme (5 Läufe): 11185 ms, mit einer Lesesumme von 11843 ms
Intel Emulator, Android 4.2 (x86)
Java: Gesamtsumme (5 Läufe): 2389 ms, mit einer Lesesumme von 2770 ms
Xamarin C #: Gesamtsumme der Zeit (5 Läufe): 1748 ms, mit einer Gesamtlesezeit von 1933 ms
Dot42 C #: Gesamtsumme der Zeit (5 Läufe): 5150 ms, mit einer Gesamtlesezeit von 5459 ms
Für mich war es auch interessant festzustellen, dass Xamarin C # auf einem neueren ARM-Gerät etwas schneller als Java und auf dem alten Nexus One etwas langsamer ist. Wenn jemand diese Tests auch ausführen möchte, lass es mich wissen und ich werde die Quellen auf GitHub aktualisieren. Es wäre besonders interessant, Ergebnisse von einem echten Android-Gerät mit Intel-Prozessor zu sehen.
Update 26.07.2013
Nur ein kurzes Update, das von Benchmark-Apps mit dem neuesten Xamarin.Android 4.8 und dem heute veröffentlichten Update dot42 1.0.1.72 neu kompiliert wurde - keine wesentlichen Änderungen gegenüber den zuvor gemeldeten Ergebnissen.
Update 30.07.2013 - bessere Ergebnisse für dot42
Dot42 wurde erneut mit Roberts (von Dot42-Herstellern) Port meines Java-Codes auf C # getestet. In meinem C # -Port, der ursprünglich für Xamarin erstellt wurde, habe ich einige native Java-Klassen wie ListArray durch eine für C # native List-Klasse usw. ersetzt. Robert hatte meinen Dot42-Quellcode nicht, portierte ihn daher erneut aus Java und verwendete die ursprünglichen Java-Klassen in Solche Orte, von denen Dot42 profitiert, werden vermutlich in Dalvik VM wie Java und nicht in Mono wie Xamarin ausgeführt. Jetzt sind die Dot42-Ergebnisse viel besser. Hier ist ein Protokoll von meinen Tests:
30.07.2013 - Dot42 testet mit mehr Java-Klassen in Dot42 C #
Intel Emulator, Android 4.2
Dot42, Gregs Code mit StringBuilder.Replace () (wie in Xamarin):
Gesamtsumme (5 Läufe): 3646 ms, mit einer Lesesumme von 3830 msDot42, Gregs Code mit String.Replace () (wie in Java und Roberts Code):
Gesamtsumme (5 Läufe): 3027 ms, mit einer Lesesumme von 3206 msDot42, Roberts Code:
Gesamtsumme (5 Läufe): 1781 ms, mit Gesamtlesung der Datei: 1999 msXamarin:
Gesamtsumme (5 Läufe): 1373 ms, mit einer Gesamtlesezeit von 1505 msJava:
Gesamtsumme der Zeit (5 Läufe): 1841 ms, mit einer Gesamtlesezeit von 2044 msARM, Samsung Galaxy Note 2, Stromsparmodus, Android 4.1.1
Dot42, Gregs Code mit StringBuilder.Replace () (wie in Xamarin):
Gesamtsumme (5 Läufe): 10875 ms, mit gelesener Datei insgesamt: 11280 msDot42, Gregs Code mit String.Replace () (wie in Java und Roberts Code):
Gesamtsumme (5 Läufe): 9710 ms, mit einer Lesesumme von 10097 msDot42, Roberts Code:
Gesamtsumme (5 Läufe): 6279 ms, mit einer Lesesumme von 6622 msXamarin:
Gesamtsumme (5 Läufe): 6201 ms, mit einer Gesamtlesezeit von 6476 msJava:
Gesamtsumme (5 Läufe): 7141 ms, mit einer Lesesumme von 7479 ms
Ich denke immer noch, dass Dot42 noch einen langen Weg vor sich hat. Java-ähnliche Klassen (z. B. ArrayList) und eine gute Leistung mit ihnen würden die Portierung von Code von Java nach C # etwas vereinfachen. Dies ist jedoch etwas, was ich wahrscheinlich nicht viel tun würde. Ich möchte lieber vorhandenen C # -Code (Bibliotheken usw.) verwenden, der native C # -Klassen (z. B. List) verwendet und der mit dem aktuellen dot42-Code langsam und mit Xamarin sehr gut funktioniert.
Greg
Antworten:
Ja, die virtuelle Mono-Maschine von Xamarin ist beeindruckender als die in Android verwendete Dalvik von Google. Ich habe es mit HTC Flyer- und Acer Iconia Tab-Tablets getestet, um den C # -Port von Android über Mono mit Java Dalvik zu vergleichen, wobei die C # -Implementierung von Android den Java-basierten Dalvik wirklich übertrifft.
quelle
https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz
Hoffe, diese Informationen helfen.
quelle
Wir haben kürzlich die Verwendung von Xamarin für eine App untersucht. Wir haben den C # -Code verwendet, den wir bereits für die Windows RT-Version unserer App geschrieben haben. Einige spezifische Details mussten für die Android-Version neu geschrieben werden.
Wir haben festgestellt, dass E / A in Xamarin C # ungefähr zweimal langsamer ist als Java. Unsere App ist stark an E / A gebunden. Wir haben die Ursache dafür noch nicht entdeckt, aber im Moment gehen wir davon aus, dass es sich um das Marshalling handelt. Während wir die meiste Zeit versuchen, in der Mono-VM zu bleiben, wissen wir nicht, wie Mono tatsächlich auf die Festplatte zugreift.
Es ist auch bezeichnend, dass unser C # -Code SQLite.NET verwendet ( https://github.com/praeclarum/sqlite-net ). Identische Abrufe mit dem SQLite.NET-Code sind auch zweimal langsamer als mit dem Java SQLite-Wrapper von Android. Nachdem ich mir den Quellcode angesehen habe, scheint er direkt an die C .dll gebunden zu sein, daher weiß ich nicht, warum er so viel langsamer ist. Eine Möglichkeit besteht darin, dass das Marshalling von Zeichenfolgen von nativ zu Java unter Android schneller ist als nativ zu C # unter Xamarin.
quelle
Dies ist ein weiterer aktualisierter Blog-Beitrag, den ich mit Ihnen teilen möchte . Er vergleicht Xamarin mit nativem Code und Cordova auf E / A und Android.
Kurz gesagt, Xamarin bietet manchmal eine bessere Leistung als nativer Code. Er testete die App-Größe, die Ladezeiten, das Laden einer Liste aus dem Azure-Dienst und die Berechnung der Primzahlen.
Genießen!
Bearbeiten: Ich habe den toten Link aktualisiert und festgestellt, dass es einen Teil 2 gibt
quelle
Hier sind einige Informationen, die ich in einem anderen Test zwischen nativen, Xamarin- und Xamarin.Forms-Lösungen (die Tests umfassen auch iOS-Leistungen) auf den beiden folgenden Geräten gefunden habe:
Samsung Galaxy A7 : Android-Betriebssystemversion: 6.0 Zentraleinheit: Octa-Core 1,9 GHz Cortex-A53 RAM: 3 GB Bildschirmauflösung: 1920 × 1080
iPhone 6s : iOS-Version: 10.3.3 Zentraleinheit: Dual-Core-Twister-RAM mit 1,84 GHz: 2 GB Bildschirmauflösung: 1334 × 750
Es werden einige gemeinsame Merkmale verglichen, von denen jedes seine eigene Anwendung hat:
Jeder Test wird mehrmals wiederholt, die Grafiken zeigen die durchschnittlichen Ergebnisse.
Hallo Welt
Rest API
Eine Reihe von Tests zur Messung der Zeit, die die App benötigt, um eine Anforderung über die REST-API zu senden und die Antwort ohne weitere Datenverarbeitung mithilfe der OpenWeatherMap-API zurück zu erhalten.
JSON-Betriebstests, die mit dem Newtonsoft Json.net-Framework durchgeführt wurden, um JSON-Objekte in allen Xamarin-Apps zu serialisieren und zu deserialisieren. Native Android-Serialisierung und -Deserialisierung mit zwei Java-Bibliotheken getestet: Jackson und GSON.
Es werden zwei Läufe durchgeführt, einer von Grund auf neu und einer mit zwischengespeicherten Informationen und Operationen
Erster Lauf :
(Native iOS JSON Operations beendet diesen Test übrigens, und Xamarin schließt sich ihm im zweiten an.)
Fotooperationen
Laden Sie zuerst Bilder mit drei verschiedenen Auflösungen:
Bei den Xamarin.Forms-Ergebnissen für diesen Test schien etwas unsicher zu sein, daher ist er nicht in der Grafik enthalten.
SQLite-Operationen
Zwei Operationen getestet:
Mit Datenbanken mit 10.000 Datensätzen. Alle Vorgänge wurden intern auf Geräten verarbeitet.
Xamarin Native (Xamarin.iOS / Xamarin.Android) zeigt sich als ziemlich gute Alternative zum nativen Code, während Xamarin.Forms in vielen Fällen langsam erscheint, aber es kann eine wirklich gute Lösung sein, um wirklich einfache Anwendungen schnell zu entwickeln.
Der vollständige Test stammt aus dieser Quelle:
https://www.altexsoft.com/blog/engineering/performance-comparison-xamarin-forms-xamarin-ios-xamarin-android-vs-android-and-ios-native-applications/
Vielen Dank, dass Sie mir die Erklärungen gegeben haben, um meine Antwort zu verbessern. Ich hoffe, das hilft ein wenig :)
quelle
Performance
Leistung ist ein vages Wort, wenn Sie nicht definieren, was Sie unter Leistung verstehen. Wenn es sich um eine einfache Rechenleistung handelt, kann Xamarin je nach Art der Berechnung schneller als Java sein.
Android wird nativ mit Multipe-Formularen geliefert, mit denen Code ausgeführt werden kann:
Es ist ziemlich offensichtlich, dass bei der Ausführung von Code die Lösung umso schneller ist, je nativer sie ist. Eine auf Laufzeit basierende Sprache schlägt niemals eine Sprache, die direkt auf der CPU ausgeführt wird.
Wenn Sie jedoch die tatsächliche Nutzungsleistung messen möchten, ist Java wahrscheinlich schneller als Xamarin.
Xamarin und warum es langsamer sein kann
Beim Vergleich von Xamarin mit einfachen alten Java-Anwendungen kann die Leistung von Xamarin sehr schnell und langsamer sein.
In einem Beispiel aus der Praxis sind Xamarin-Anwendungen sehr wahrscheinlich langsamer als Java-Anwendungen, da viele Android / Java-Aufrufe (Systemaufrufe) mithilfe sogenannter Bindungen an und von der Xamarin-Laufzeit delegiert werden müssen.
Es gibt einige verschiedene Arten von Bindungen, die wichtig zu wissen sind:
Bindungen sind in Bezug auf die Leistung sehr, sehr kostspielig. Das Aufrufen einer C ++ - Methode aus Java erhöht den Aufrufaufwand erheblich. Das Aufrufen einer C ++ - Methode aus C ++ heraus ist um ein Vielfaches schneller.
Aber nicht nur JNI-Anrufe sind teuer, sondern auch Anrufe von und zu MCW und ACW. Xamarin-Anwendungen in der realen Welt führen viele Aufrufe mithilfe von Bindungen durch. Aus diesem Grund kann (und wird) die Verwendung einer Xamarin-Anwendung in der realen Welt langsamer sein als eine einfache alte Java-Anwendung. Abhängig davon, wie die Xamarin-Anwendung entwickelt wurde, ist es sehr wahrscheinlich, dass der Benutzer den Unterschied nicht einmal bemerkt.
TLDR / Fazit: Xamarin muss alle Arten von Bindungen verwenden, die zeitaufwändig sind.
quelle
Es sind ziemlich alte Tests, könnten aber relevant sein: https://github.com/EgorBo/Xamarin.Android-vs-Java
Arithmetischer Test
Sammlungen, Generika, benutzerdefinierte Werttypen
Arbeiten mit Strings
UPD: Neue Daten mit Google Pixel 2 (danke yousha-aleayoub )
quelle