Me encontré con Xamarin afirma 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ó pruebas comparativas reales en código Java y C # muy similar en diferentes plataformas de Android para verificar tales afirmaciones, podría publicar el código y los resultados?
Añadido 18 de junio de 2013
Como no hubo respuesta y no pude encontrar esos puntos de referencia hechos por otros, decidí hacer mis propias pruebas. Desafortunadamente, mi pregunta permanece "bloqueada", por lo que no puedo publicar esto como respuesta, solo edito la pregunta. Vote para volver a abrir esta pregunta. Para C #, utilicé 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
Porté mi clase de extractor de oraciones a C # (desde mi aplicación @Voice Aloud Reader) y ejecuté 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 publica a continuación. Probé solo las versiones "Release", sin la depuración habilitada.
HTC Nexus One Android 2.3.7 (API 10) - ROM de CyanogenMod
Java: Gran tiempo total (5 ejecuciones): 12361 ms, con un total de lectura de archivos: 13304 ms
C #: tiempo total total (5 ejecuciones): 17504 ms, con lectura total de archivos: 17956 ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM
Java: Gran tiempo total (5 ejecuciones): 8947 ms, con lectura total de archivos: 9186 ms
C #: Gran tiempo total (5 ejecuciones): 9884 ms, con lectura total 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 lectura total de archivos: 3127 ms
C #: Gran tiempo total (5 ejecuciones): 2049 ms, con un total de lectura de archivos: 2182 ms
Emulador: Intel (Android 2.3.7, API 10)
Java: gran tiempo total (5 ejecuciones): 2992 ms, con lectura total de archivos: 3591 ms
C #: tiempo total total (5 ejecuciones): 2049 ms, con lectura total 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 ejecuciones): 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 de expresiones regulares, 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 funcionó mejor que el código Xamarin C #. La mayor diferencia estaba en Android 2.3, donde el código C # se ejecuta a aprox. 70% de la velocidad de Java.
En el emulador Intel (con tecnología Intel HAX, el emulador se ejecuta en modo virt veloz), 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. ¿Quizás el código de la máquina virtual Mono y las bibliotecas están mucho mejor optimizados en Intel que en ARM?
Editar 8 de julio de 2013
Acabo de instalar el emulador Genymotion de Android, que se ejecuta en Oracle VirtualBox, y nuevamente utiliza un procesador Intel nativo, no emula 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 ejecuciones): 2069 ms, con lectura total de archivos: 2248 ms
C #: Gran tiempo total (5 ejecuciones): 1543 ms, con lectura total 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 mencionan algunos cambios en el tiempo de ejecución de Mono también. Decidí probar rápidamente algunos dispositivos ARM, y una gran sorpresa: los números de C # mejoraron:
BN Nook XD +, ARM (Android 4.0)
Java: Gran tiempo total (5 ejecuciones): 8103 ms, con lectura total de archivos: 8569 ms
C #: Gran tiempo total (5 ejecuciones): 7951 ms, con un total de lectura de archivos: 8161 ms
¡Guauu! C # ahora es 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 lectura total 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 dieron 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: modo de ahorro de energía. En Nook, estaba deshabilitado, en la Nota 2 - habilitado. Decidió probar con el modo de ahorro de energía deshabilitado (como con habilitado, también limita la velocidad del procesador):
Samsung Galaxy Note 2 - ARM (Android 4.1.1), ahorro de energía deshabilitado
Java: Gran tiempo total (5 ejecuciones): 7153 ms, con lectura total de archivos: 7459 ms
C #: Gran tiempo total (5 ejecuciones): 6906 ms, con lectura total de archivos: 7070 ms
Ahora, sorprendentemente, C # es también un poco más rápido que Java en el procesador ARM. Gran mejora!
Editar 12 de julio de 2013
Todos sabemos que nada supera la velocidad del código nativo, y no estaba satisfecho con el rendimiento de mi divisor de oraciones en Java o C #, particularmente que necesito mejorarlo (y así hacerlo aún más lento). Decidí reescribirlo en C ++. Aquí hay una comparación pequeña (es decir, un conjunto de archivos más pequeño que las pruebas anteriores, por otras razones) de la velocidad de nativo frente a 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 ejecuciones): 537 ms, con lectura total de archivos: 657 ms
Brazo nativo: Gran tiempo total (5 carreras): 458 ms, con lectura total de archivos: 587 ms
Parece que para mi prueba en particular, el código nativo es de 6 a 7 veces más rápido que Java. Advertencia: no podía usar la clase std :: regex en Android, así que tuve que escribir mis propias rutinas especializadas buscando saltos de párrafo o etiquetas html. Mis pruebas iniciales del mismo código en una PC usando regex fueron entre 4 y 5 veces más rápidas que Java.
¡Uf! Al despertar memoria cruda con punteros char * o wchar * nuevamente, ¡instantáneamente me sentí 20 años más joven! :)
Editar 15 de julio de 2013
(Consulte a continuación, con ediciones del 30/07/2013, para obtener resultados mucho mejores con Dot42)
Con cierta dificultad, logré portar 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 3 veces (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, por lo que usé la clase Java.Util.Regex en su lugar, y Java.Util.Regex.Pattern.Split () , así que en este lugar en particular en el código, existe esta pequeña diferencia. Sin embargo, no debería ser un gran problema. Dot42 compila el código Dalvik (DEX), por lo que coopera con Java en Android de forma nativa, no necesita interoperabilidad costosa de C # a Java como Xamarin.
Solo para comparar, también ejecuto la prueba en dispositivos ARM: aquí el código Dot42 es "solo" 2 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 ejecuciones): 13935 ms, con lectura total de archivos: 14465 ms
Dot42 C #: Gran tiempo total (5 ejecuciones): 26000 ms, con lectura total de archivos: 27168 ms
Samsung Galaxy Note 2, Android 4.1.1 (ARM)
Java: Gran tiempo total (5 ejecuciones): 6895 ms, con lectura total de archivos: 7275 ms
Xamarin C #: Gran tiempo total (5 ejecuciones): 6466 ms, con un total de lectura de archivos: 6720 ms
Dot42 C #: Gran tiempo total (5 ejecuciones): 11185 ms, con un total de lectura de archivos: 11843 ms
Emulador Intel, Android 4.2 (x86)
Java: Gran tiempo total (5 ejecuciones): 2389 ms, con un total de lectura de archivos: 2770 ms
Xamarin C #: Gran tiempo total (5 ejecuciones): 1748 ms, con lectura total de archivos: 1933 ms
Dot42 C #: Gran tiempo total (5 ejecuciones): 5150 ms, con un total de lectura de archivos: 5459 ms
Para mí, también fue interesante observar que Xamarin C # es ligeramente 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 le gustaría ejecutar estas pruebas también, avíseme 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 de 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 C # hecho inicialmente para Xamarin, reemplacé algunas clases nativas de Java, como ListArray, con la clase List nativa de C #, etc. Robert no tenía mi código fuente Dot42, por lo que lo portó nuevamente desde Java y usó clases Java originales en Supongo que esos lugares, que benefician a Dot42, se ejecutan 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/07/2013 - Dot42 prueba con más clases de Java en Dot42 C #
Emulador Intel, Android 4.2
Dot42, el código de Greg usando StringBuilder.Replace () (como en Xamarin):
Tiempo total total (5 ejecuciones): 3646 ms, con un total de lectura de archivos: 3830 msDot42, el código de Greg usando String.Replace () (como en Java y el código de Robert): Tiempo
total total (5 ejecuciones): 3027 ms, con lectura total de archivos: 3206 msDot42, Código de Robert:
Gran tiempo total (5 carreras): 1781 ms, con lectura total de archivos: 1999 msXamarin:
Gran tiempo total (5 ejecuciones): 1373 ms, con lectura total de archivos: 1505 msJava:
Gran tiempo total (5 ejecuciones): 1841 ms, con lectura total de archivos: 2044 msBRAZO, Samsung Galaxy Note 2, ahorro de energía apagado, Android 4.1.1
Dot42, el código de Greg usando StringBuilder.Replace () (como en Xamarin):
Tiempo total total (5 ejecuciones): 10875 ms, con lectura total de archivos: 11280 msDot42, el código de Greg usando String.Replace () (como en Java y el código de Robert): Tiempo
total total (5 ejecuciones): 9710 ms, con un total de lectura de archivos: 10097 msDot42, Código de Robert:
Gran tiempo total (5 ejecuciones): 6279 ms, con lectura total de archivos: 6622 msXamarin:
Gran tiempo total (5 ejecuciones): 6201 ms, con lectura total de archivos: 6476 msJava:
Gran tiempo total (5 ejecuciones): 7141 ms, con lectura total de archivos: 7479 ms
Sigo pensando que Dot42 tiene un largo camino por recorrer. Tener clases similares a Java (por ejemplo, ArrayList) y un buen rendimiento con ellas facilitaría un poco la transferencia de 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 nativas de C # (por ejemplo, Lista), y que funcionaría lentamente con el código dot42 actual, y muy bien con Xamarin.
Greg