visual tutorial studio microsoft code apps c# java android xamarin dot42

c# - studio - xamarin tutorial



¿Alguien tiene puntos de referencia(código y resultados) que comparen el rendimiento de las aplicaciones de Android escritas en Xamarin C#y Java? (7)

Me encontré con las afirmaciones de Xamarin de que su implementación Mono en Android y sus aplicaciones compiladas en C # son más rápidas que el código Java. ¿Alguien realizó puntos de referencia reales en Java y C # muy similares en diferentes plataformas de Android para verificar tales afirmaciones, podría publicar el código y los resultados?

Añadido el 18 de junio de 2013

Como no hubo respuesta y no se pudieron encontrar los puntos de referencia realizados por otros, decidí hacer mis propias pruebas. Desafortunadamente, mi pregunta permanece "bloqueada", así que no puedo publicar esto como la respuesta, solo edito la pregunta. Por favor vote para volver a abrir esta pregunta. Para C #, usé Xamarin.Android Ver. 4.7.09001 (beta). El código fuente, todos los datos que utilicé para probar y compilar paquetes APK están en GitHub:

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

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

Si alguien quisiera repetir mis pruebas en otros dispositivos o emuladores, también me interesaría conocer los resultados.

Resultados de mis pruebas

Puse mi clase de extractor de oraciones en C # (desde mi aplicación @Voice Aloud Reader) y realicé algunas pruebas en 10 archivos HTML en inglés, ruso, francés, polaco y checo. Cada ejecución se realizó 5 veces en los 10 archivos, y el tiempo total para 3 dispositivos diferentes y un emulador se publican a continuación. Probé las compilaciones "Release" solamente, sin la depuración habilitada.

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

Java: Gran tiempo total (5 ejecuciones): 12361 ms, con lectura total de archivos: 13304 ms

C #: Gran tiempo total (5 carreras): 17504 ms, con un total de lectura de archivos: 17956 ms

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

Java: Gran tiempo total (5 carreras): 8947 ms, con un total de lectura de archivos: 9186 ms

C #: Gran tiempo total (5 ejecuciones): 9884 ms, con un total de lectura de archivos: 10247 ms

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

Java: Gran tiempo total (5 ejecuciones): 9742 ms, con lectura total de archivos: 10111 ms

C #: Gran tiempo total (5 ejecuciones): 10459 ms, con lectura total de archivos: 10696 ms

Emulador - Intel (Android 4.2, API 17)

Java: Gran tiempo total (5 ejecuciones): 2699 ms, con un total de lectura de archivos: 3127 ms

C #: Gran tiempo total (5 corridas): 2049 ms, con un total de lectura de archivos: 2182 ms

Emulador - Intel (Android 2.3.7, API 10)

Java: Gran tiempo total (5 carreras): 2992 ms, con un total de lectura de archivos: 3591 ms

C #: Gran tiempo total (5 carreras): 2049 ms, con un total de lectura de archivos: 2257 ms

Emulador - Brazo (Android 4.0.4, API 15)

Java: Gran tiempo total (5 ejecuciones): 41751 ms, con un total de lectura de archivos: 43866 ms

C #: Gran tiempo total (5 corridas): 44136 ms, con un total de lectura de archivos: 45109 ms

Breve discusión

Mi código de prueba contiene principalmente análisis de texto, reemplazo y búsquedas Regex, quizás para otro código (por ejemplo, más operaciones numéricas) los resultados serían diferentes. En todos los dispositivos con procesadores ARM, Java se desempeñó mejor que el código C # de Xamarin. La mayor diferencia fue en Android 2.3, donde el código C # se ejecuta a aprox. 70% de la velocidad de Java.

En el emulador Intel (con la tecnología Intel HAX, el emulador se ejecuta en el modo virt virt), el código Xamarin C # ejecuta mi código de muestra mucho más rápido que Java, aproximadamente 1.35 veces más rápido. ¿Es posible que las bibliotecas y el código de la máquina virtual Mono estén mucho mejor optimizados en Intel que en ARM?

Editar julio 8, 2013

Acabo de instalar el emulador de Android Genymotion, que se ejecuta en Oracle VirtualBox, y nuevamente este utiliza el procesador Intel nativo, no emulando el procesador ARM. Al igual que con el emulador Intel HAX, nuevamente C # se ejecuta aquí mucho más rápido. Aquí están mis resultados:

Emulador Genymotion - Intel (Android 4.1.1, API 16)

Java: Gran tiempo total (5 carreras): 2069 ms, con un total de lectura de archivos: 2248 ms

C #: Gran tiempo total (5 carreras): 1543 ms, con un total de lectura de archivos: 1642 ms

Luego noté que había una actualización de Xamarin.Android beta, versión 4.7.11, con notas de la versión que mencionaban algunos cambios en el tiempo de ejecución de Mono también. Decidimos probar rápidamente algunos dispositivos ARM y una gran sorpresa: los números C # mejoraron:

BN Nook XD +, ARM (Android 4.0)

Java: Gran tiempo total (5 ejecuciones): 8103 ms, con un total de lectura de archivos: 8569 ms

C #: Gran tiempo total (5 ejecuciones): 7951 ms, con un total de lectura de archivos: 8161 ms

¡Guauu! C # es ahora mejor que Java? Decidí repetir la prueba en mi Galaxy Note 2:

Samsung Galaxy Note 2 - ARM (Android 4.1.1)

Java: Gran tiempo total (5 ejecuciones): 9675 ms, con un total de lectura de archivos: 10028 ms

C #: Gran tiempo total (5 ejecuciones): 9911 ms, con un total de lectura de archivos: 10104 ms

Aquí C # parece ser solo un poco más lento, pero estos números me hicieron una pausa: ¿Por qué el tiempo es más largo que en Nook HD +, aunque Note 2 tiene un procesador más rápido? La respuesta: el modo de ahorro de energía. En Nook, estaba deshabilitado, en Nota 2 - habilitado. Decidió probar con el modo de ahorro de energía desactivado (como habilitado, también limita la velocidad del procesador):

Samsung Galaxy Note 2 - ARM (Android 4.1.1), ahorro de energía desactivado

Java: Gran tiempo total (5 ejecuciones): 7153 ms, con un total de lectura de archivos: 7459 ms

C #: Gran tiempo total (5 ejecuciones): 6906 ms, con un total de lectura de archivo: 7070 ms

Ahora, sorprendentemente, C # también es un poco más rápido que Java en el procesador ARM. Gran mejora!

Editar julio 12, 2013

Todos sabemos, que nada supera el código nativo para la velocidad, y no estaba satisfecho con el rendimiento de mi división de sentencias en Java o C #, especialmente porque necesito mejorarlo (y por lo tanto hacerlo más lento). Decidió reescribirlo en C ++. Aquí hay una pequeña comparación (es decir, un conjunto de archivos más pequeño que las pruebas anteriores, por otras razones) de la velocidad de nativo contra Java en mi Galaxy Note 2, con el modo de ahorro de energía desactivado:

Java: Gran tiempo total (5 ejecuciones): 3292 ms, con un total de lectura de archivos: 3454 ms

Pulgar nativo: Gran tiempo total (5 carreras): 537 ms, con un total de lectura de archivos: 657 ms

Brazo nativo: Gran tiempo total (5 carreras): 458 ms, con un total de lectura de archivos: 587 ms

Parece que para mi prueba particular, el código nativo es de 6 a 7 veces más rápido que Java. Advertencia: no se podía usar la clase std :: regex en Android, así que tuve que escribir mis propias rutinas especializadas en la búsqueda de saltos de párrafos o etiquetas html. Mis pruebas iniciales del mismo código en una PC con expresiones regulares, fueron de 4 a 5 veces más rápidas que las de Java.

¡Uf! Al despertar la memoria original con los punteros char * o wchar * otra vez, ¡me sentí instantáneamente 20 años más joven! :)

Editar julio 15, 2013

(Por favor, vea más abajo, con ediciones del 30/7/2013, para obtener mejores resultados con Dot42)

Con algunas dificultades, logré transferir mis pruebas de C # a Dot42 (versión 1.0.1.71 beta), otra plataforma de C # para Android. Los resultados preliminares muestran que el código Dot42 es aproximadamente 3x (3 veces) más lento que Xamarin C # (v. 4.7.11), en un emulador Intel Android. Un problema es que la clase System.Text.RegularExpressions en Dot42 no tiene la función Split () que usé en las pruebas de Xamarin, así que usé la clase Java.Util.Regex y Java.Util.Regex.Pattern.Split () Entonces, en este lugar particular en el código, hay una pequeña diferencia. Sin embargo, no debería ser un gran problema. Dot42 se compila en el código Dalvik (DEX), por lo que coopera con Java en Android de forma nativa, no necesita una interoperación costosa de C # a Java como Xamarin.

Solo para comparación, también ejecuto la prueba en dispositivos ARM; aquí el código Dot42 es "solo" dos veces más lento que Xamarin C #. Aquí están mis resultados:

HTC Nexus One Android 2.3.7 (ARM)

Java: Gran tiempo total (5 ejecuciones): 12187 ms, con lectura total de archivos: 13200 ms

Xamarin C #: Gran tiempo total (5 carreras): 13935 ms, con un total de lectura de archivos: 14465 ms

Dot42 C #: Gran tiempo total (5 carreras): 26000 ms, con un total de lectura de archivos: 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: Gran tiempo total (5 carreras): 6895 ms, con un total de lectura de archivos: 7275 ms

Xamarin C #: Gran tiempo total (5 carreras): 6466 ms, con un total de lectura de archivos: 6720 ms

Dot42 C #: Gran tiempo total (5 carreras): 11185 ms, con un total de lectura de archivos: 11843 ms

Emulador de Intel, Android 4.2 (x86)

Java: Gran tiempo total (5 carreras): 2389 ms, con un total de lectura de archivos: 2770 ms

Xamarin C #: Gran tiempo total (5 carreras): 1748 ms, con un total de lectura de archivos: 1933 ms

Dot42 C #: Gran tiempo total (5 carreras): 5150 ms, con un total de lectura de archivos: 5459 ms

Para mí, también fue interesante observar que Xamarin C # es un poco más rápido que Java en un dispositivo ARM más nuevo y un poco más lento en el antiguo Nexus One. Si a alguien también le gustaría realizar estas pruebas, hágamelo saber y actualizaré las fuentes en GitHub. Sería particularmente interesante ver los resultados de un dispositivo Android real con procesador Intel.

Actualización 26/07/2013

Solo una actualización rápida, compilada nuevamente por aplicaciones de referencia con el último Xamarin.Android 4.8 y también con la actualización dot42 1.0.1.72 lanzada hoy, sin cambios significativos en los resultados informados anteriormente.

Actualización 30/07/2013 - mejores resultados para dot42

Vuelva a probar Dot42 con el puerto de Robert (de los fabricantes de dot42) de mi código Java a C #. En mi puerto de C # realizado inicialmente para Xamarin, reemplacé algunas clases nativas de Java, como ListArray, con la clase de lista nativa de C #, etc. Robert no tenía mi código fuente Dot42, así que lo portó de nuevo desde Java y usó clases originales de Java en Tales lugares, lo que beneficia a Dot42, supongo que se ejecuta en Dalvik VM, como Java, y no en Mono, como Xamarin. Ahora los resultados de Dot42 son mucho mejores. Aquí hay un registro de mis pruebas:

30/7/2013 - Dot42 prueba con más clases de Java en Dot42 C #

Emulador de Intel, Android 4.2

Dot42, el Código de Greg usando StringBuilder.Replace () (como en Xamarin):
Gran tiempo total (5 carreras): 3646 ms, con lectura total de archivos: 3830 ms

Dot42, el código de Greg usando String.Replace () (como en Java y el código de Robert):
Gran tiempo total (5 carreras): 3027 ms, con lectura total de archivos: 3206 ms

Dot42, Código de Robert:
Gran tiempo total (5 carreras): 1781 ms, con lectura total de archivos: 1999 ms

Xamarin:
Gran tiempo total (5 carreras): 1373 ms, con lectura total de archivos: 1505 ms

Java:
Gran tiempo total (5 carreras): 1841 ms, con lectura total de archivos: 2044 ms

ARM, Samsung Galaxy Note 2, apagado de energía, Android 4.1.1

Dot42, el Código de Greg usando StringBuilder.Replace () (como en Xamarin):
Gran tiempo total (5 carreras): 10875 ms, con lectura total de archivos: 11280 ms

Dot42, el código de Greg usando String.Replace () (como en Java y el código de Robert):
Gran tiempo total (5 carreras): 9710 ms, con un total de lectura de archivo: 10097 ms

Dot42, Código de Robert:
Gran tiempo total (5 carreras): 6279 ms, con lectura total de archivos: 6622 ms

Xamarin:
Gran tiempo total (5 carreras): 6201 ms, con un total de lectura de archivos: 6476 ms

Java:
Gran tiempo total (5 carreras): 7141 ms, con lectura total de archivos: 7479 ms

Todavía creo que Dot42 tiene un largo camino por recorrer. Tener clases similares a Java (por ejemplo, ArrayList) y un buen rendimiento con ellas haría un poco más fácil portar código de Java a C #. Sin embargo, esto es algo que probablemente no haría mucho. Preferiría usar el código C # existente (bibliotecas, etc.), que usará clases C # nativas (por ejemplo, Lista), y funcionaría lentamente con el código dot42 actual, y muy bien con Xamarin.

Greg


Actuación

Rendimiento es una palabra vaga si no define lo que quiere decir por rendimiento, si se trata de un rendimiento de cómputo simple Xamarin puede ser más rápido que Java dependiendo de la naturaleza del cálculo.

Android viene de forma nativa con formularios multipe para ejecutar código en:

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

Es bastante obvio que al ejecutar código, cuanto más nativa sea la solución, más rápida será. Un lenguaje basado en tiempo de ejecución nunca superará un idioma que se ejecute directamente en la CPU.

Pero, por otro lado, si desea medir el rendimiento del uso en la vida real, Java es muy rápido que Xamarin.

Xamarin y por qué puede ser más lento.

Al comparar Xamarin con aplicaciones Java antiguas, el rendimiento puede ser mucho más rápido para Xamarin, ya que puede ser más lento.

En un ejemplo del mundo real, es muy probable que las aplicaciones Xamarin sean más lentas que las aplicaciones Java porque muchas de las llamadas de Android / Java (sistema) deben delegarse desde y hacia el tiempo de ejecución de Xamarin utilizando los llamados enlaces.

Hay algunos tipos diferentes de enlaces que es importante saber:

  • JNI (Java Native Interface): el enlace utilizado en muchas aplicaciones de Android para interactuar entre el código Java (SDK) y el código C ++ nativo (NDK).
  • MCW (Managed Callable Wrappers): un enlace que está disponible en Xamarin para interactuar desde el código C # administrado al código Java (tiempo de ejecución de Android).
  • ACW (Android Callable Wrappers): un enlace que está disponible en Xamarin para interactuar desde el código Java (tiempo de ejecución de Android) al código C # administrado.

Más información sobre MCW y ACW aquí: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

Los enlaces son en términos de rendimiento muy costoso. Invocar un método C ++ desde Java agrega una gran sobrecarga en el tiempo de llamada, llamar a un método C ++ desde C ++ es mucho más rápido.

Alguien hizo una prueba de rendimiento para calcular cuántas operaciones de Java en promedio cuesta una llamada JNI: ¿Cuál es la sobrecarga cuantitativa de hacer una llamada JNI?

Pero no solo las llamadas JNI son costosas, sino también las llamadas hacia y desde MCW y ACW. Las aplicaciones de Xamarin en el mundo real realizan muchas llamadas utilizando enlaces y debido a este uso en el mundo real de una aplicación de Xamarin puede ser (y será en general) más lenta que una aplicación Java simple. Sin embargo, dependiendo de cómo se diseñó la aplicación Xamarin, es muy probable que el usuario ni siquiera note la diferencia.

TLDR / Conclusión: Xamarin necesita usar todos los enlaces, que son costosos en tiempo.

Además de los enlaces, hay muchos otros factores involucrados cuando se habla de rendimiento en el mundo real, por ejemplo: tamaño del binario, carga de la aplicación en la memoria, operaciones de E / S y muchos más. Una publicación del blog que investiga algunas de estas cosas se puede encontrar aquí: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms


Aquí hay algunas informaciones que encontré en otra prueba entre las soluciones nativas, Xamarin y Xamarin.Forms (las pruebas también incluyen el rendimiento de iOS) en los dos dispositivos siguientes:

Samsung Galaxy A7 : versión del sistema operativo Android: 6.0 Unidad de procesamiento central: Octa-core 1.9 GHz Cortex-A53 RAM: 3 GB Resolución de pantalla: 1920 × 1080

iPhone 6s : Versión de iOS: 10.3.3 Unidad de procesamiento central: Twister RAM de 1,84 GHz de doble núcleo: 2 GB Resolución de pantalla: 1334 × 750

La comparación se realiza en algunas características comunes, cada una con su propia aplicación:

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

Cada prueba se repite varias veces, los gráficos muestran los resultados promedio.

Hola Mundo

API de descanso

Conjunto de pruebas destinadas a medir el tiempo que tarda la aplicación en enviar una solicitud a través de la API REST y recibir la respuesta sin procesamiento adicional de datos, utilizando la API OpenWeatherMap.

Pruebas de operaciones JSON realizadas con el framework Newtonsoft Json.net para serializar y deserializar objetos JSON en todas las aplicaciones Xamarin. La serialización y deserialización nativas de Android se probaron utilizando dos bibliotecas de Java: Jackson y GSON.

Se realizan dos carreras, una primera desde cero y una segunda con información y operaciones almacenadas en caché

Primer intento :

(Las operaciones JSON nativas de iOS están matando esta prueba por cierto, y Xamarin se une a la segunda)

Operaciones de fotos

Primera carga en imágenes con tres resoluciones diferentes:

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

Algo no estaba seguro acerca de los resultados de Xamarin.Forms para esta prueba, por lo que no se incluye en el gráfico.

Operaciones SQLite

Dos operaciones probadas:

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

Con bases de datos que tienen 10.000 registros. Todas las operaciones fueron procesadas internamente en dispositivos.

Xamarin Native (Xamarin.iOS / Xamarin.Android) se muestran como alternativas bastante buenas al código nativo, mientras que Xamarin.Forms parece lento en muchos casos, pero puede ser una muy buena solución para desarrollar aplicaciones realmente simples rápidamente.

Prueba completa proviene de esta fuente:

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

Gracias por darme las explicaciones para mejorar mi respuesta, espero que esto ayude un poco :)


Recientemente investigamos el uso de Xamarin para una aplicación. Utilizamos el código C # que ya habíamos escrito para la versión Windows RT de nuestra aplicación. Algunos detalles específicos tuvieron que ser reescritos para la versión de Android.

Lo que descubrimos es que la E / S en Xamarin C # es aproximadamente 2 veces más lenta que Java. Nuestra aplicación está fuertemente vinculada a I / O. Aún no hemos descubierto la causa de esto, pero en este momento estamos asumiendo que se debe al cálculo. Si bien intentamos permanecer dentro de la VM Mono la mayor parte del tiempo, no sabemos cómo Mono accede al disco.

También indica que nuestro código C # utiliza SQLite.NET ( https://github.com/praeclarum/sqlite-net ). Las recuperaciones idénticas que utilizan el código SQLite.NET también son 2 veces más lentas que usar el contenedor Java SQLite de Android. Después de mirar el código fuente, parece que se enlaza directamente con el C .dll, así que no sé por qué es mucho más lento. Una posibilidad es que las cadenas de cálculo desde nativas a Java pueden ser más rápidas en Android que las nativas a C # en Xamarin.


Sí, la máquina virtual Mono de Xamarin es más impresionante que el Dalvik de Google utilizado en Android. Lo he probado con las tabletas HTC Flyer y Acer Iconia Tab para comparar el puerto C # de Android a través de Mono contra Java Dalvik, con la implementación C # de Android y realmente derrotando al Dalvik basado en Java.


Son pruebas bastante antiguas pero podrían ser relevantes: https://github.com/EgorBo/Xamarin.Android-vs-Java

Prueba aritmética

Colecciones, genéricos, tipos de valores personalizados.

Trabajando con cuerdas

UPD: nuevos datos con Google Pixel 2 (gracias yousha-aleayoub )