c# - visual - usar xamarin




Alguém tem benchmarks(código e resultados) comparando o desempenho de aplicativos Android escritos em Xamarin C#e Java? (5)

atuação

O desempenho é uma palavra vaga se você não definir o que entende por desempenho, se for um desempenho simples de computação, o Xamarin pode ser mais rápido que o Java, dependendo da natureza do cálculo.

O Android nativly vem com formulários multipe para executar o código em:

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

É bastante óbvio que, ao executar o código, quanto mais nativa a solução, mais rápido ela será. Uma linguagem baseada em tempo de execução nunca vai bater uma linguagem que roda diretamente na CPU.

Mas, por outro lado, se você quiser medir o desempenho de uso da vida real, o Java será mais rápido do que o Xamarin.

Xamarin e porque pode ser mais lento

Ao comparar o Xamarin com aplicativos Java antigos simples, o desempenho pode muito bem ser mais rápido para o Xamarin, já que ele pode ser mais lento.

Em um exemplo do mundo real, é muito provável que os aplicativos Xamarin sejam mais lentos do que os aplicativos Java, porque muitas chamadas do Android / Java (sistema) precisam ser delegadas para e a partir do tempo de execução do Xamarin usando as chamadas ligações.

Existem alguns tipos diferentes de ligações que são importantes saber:

  • JNI (Java Native Interface): A ligação usada em muitos aplicativos do Android para fazer a interface entre o código Java (SDK) e o código C ++ nativo (NDK).
  • MCW (Managed Callable Wrappers): Uma ligação que está disponível no Xamarin para fazer interface do código C # gerenciado para o código Java (tempo de execução do Android).
  • ACW (Android Callable Wrappers): Uma ligação disponível no Xamarin para fazer a interface do código Java (tempo de execução do Android) para o código C # gerenciado.

Mais sobre o MCW e o ACW aqui: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

As ligações são em termos de desempenho muito muito caras. Invocar um método C ++ do Java adiciona uma enorme sobrecarga no tempo de chamada, chamando um método C ++ de dentro do C ++ é muitas, muitas vezes mais rápido.

Alguém fez um teste de desempenho para calcular quantas operações Java, em média, custa uma chamada JNI: Qual é a sobrecarga quantitativa de fazer uma chamada JNI?

Mas não apenas as chamadas JNI são caras, assim como as chamadas de e para o MCW e o ACW. Aplicativos Xamarin do mundo real fazem muitas chamadas usando ligações e, por causa disso, o uso real de um aplicativo Xamarin pode ser (e será, em geral) mais lento do que um simples aplicativo Java antigo. No entanto, dependendo de como o aplicativo Xamarin foi projetado, é muito provável que o usuário nem notará a diferença.

TLDR / Conclusão: O Xamarin precisa usar als bindings, que são caros.

Além das associações, há muitos outros fatores envolvidos quando se fala em desempenho no mundo real, por exemplo: tamanho do binário, carregamento do aplicativo na memória, operações de E / S e muito mais. Uma postagem de blog que investiga algumas dessas coisas pode ser encontrada aqui: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms

Me deparei com Xamarin afirma que sua implementação Mono no Android e seus aplicativos compilados C # são mais rápidos do que o código Java. Alguém realizou benchmarks reais em códigos Java e C # muito semelhantes em diferentes plataformas Android para verificar tais alegações, poderia postar o código e os resultados?

Adicionado em 18 de junho de 2013

Como não havia resposta e não consegui encontrar esses benchmarks feitos por outros, decidi fazer meus próprios testes. Infelizmente, minha pergunta permanece "bloqueada", portanto, não posso postar isso como a resposta, apenas edite a pergunta. Por favor vote para reabrir esta questão. Para C #, usei o Xamarin.Android Ver. 4.7.09001 (beta). O código fonte, todos os dados que usei para testar e compilar os pacotes APK estão no GitHub:

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

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

Se alguém quiser repetir meus testes em outros dispositivos ou emuladores, eu gostaria de saber os resultados também.

Resultados do meu teste

Eu portei minha classe extrator de sentenças para C # (do meu aplicativo @Voice Aloud Reader) e executei alguns testes em 10 arquivos HTML em inglês, russo, francês, polonês e tcheco. Cada execução foi realizada 5 vezes em todos os 10 arquivos, e o tempo total para 3 dispositivos diferentes e um emulador são postados abaixo. Eu testei "Release" apenas para builds, sem depuração habilitada.

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

Java: tempo total total (5 execuções): 12361 ms, com total de leituras: 13304 ms

C #: tempo total total (5 execuções): 17504 ms, com total de leitura de arquivo: 17956 ms

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

Java: tempo total total (5 execuções): 8947 ms, com total de leituras: 9186 ms

C #: tempo total total (5 execuções): 9884 ms, com total de leitura de arquivo: 10247 ms

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

Java: tempo total total (5 execuções): 9742 ms, com total de leitura de arquivo: 10111 ms

C #: tempo total total (5 execuções): 10459 ms, com total de leituras: 10696 ms

Emulador - Intel (Android 4.2, API 17)

Java: tempo total total (5 execuções): 2699 ms, com total de leitura de arquivo: 3127 ms

C #: tempo total total (5 execuções): 2049 ms, com total de leitura de arquivo: 2182 ms

Emulador - Intel (Android 2.3.7, API 10)

Java: tempo total total (5 execuções): 2992 ms, com total de leituras: 3591 ms

C #: tempo total total (5 execuções): 2049 ms, com total de leitura de arquivo: 2257 ms

Emulador - Braço (Android 4.0.4, API 15)

Java: tempo total total (5 execuções): 41751 ms, com total de leituras: 43866 ms

C #: tempo total total (5 execuções): 44136 ms, com total de leitura de arquivo: 45109 ms

Breve discussão

Meu código de teste contém principalmente análise de texto, substituição e pesquisas Regex, talvez para outro código (por exemplo, mais operações numéricas) os resultados seriam diferentes. Em todos os dispositivos com processadores ARM, o Java teve um desempenho melhor do que o código Xamarin C #. A maior diferença foi no Android 2.3, onde o código C # é executado em aprox. 70% da velocidade do Java.

No emulador Intel (com a tecnologia Intel HAX, o emulador é executado no modo virt virt rápido), o código Xamarin C # executa meu código de amostra muito mais rápido que o Java - cerca de 1,35 vez mais rápido. Talvez o código e as bibliotecas de máquinas virtuais Mono sejam muito melhor otimizados na Intel do que no ARM?

Editar 8 de julho de 2013

Acabei de instalar o emulador Genymotion Android, que roda no Oracle VirtualBox, e novamente este usa processador nativo da Intel, não emulando o processador ARM. Assim como no emulador Intel HAX, novamente o C # é executado muito mais rápido. Aqui estão meus resultados:

Emulador Genymotion - Intel (Android 4.1.1, API 16)

Java: tempo total total (5 execuções): 2069 ms, com total de leitura de arquivo: 2248 ms

C #: tempo total total (5 execuções): 1543 ms, com total de leitura de arquivo: 1642 ms

Então notei que havia uma atualização para o Xamarin.Android beta, versão 4.7.11, com notas de lançamento mencionando algumas mudanças no tempo de execução Mono também. Decidiu testar rapidamente alguns dispositivos ARM e grandes surpresas - números C # melhoraram:

BN Nook XD +, ARM (Android 4.0)

Java: tempo total total (5 execuções): 8103 ms, com total de leituras: 8569 ms

C #: tempo total total (5 execuções): 7951 ms, com total de leitura de arquivo: 8161 ms

Uau! C # agora é melhor que Java? Decidiu repetir o teste no meu Galaxy Note 2:

Samsung Galaxy Note 2 - ARM (Android 4.1.1)

Java: tempo total total (5 execuções): 9675 ms, com total de leitura de arquivo: 10028 ms

C #: tempo total total (5 execuções): 9911 ms, com total de leituras: 10104 ms

Aqui, o C # parece ser apenas um pouco mais lento, mas esses números me deram uma pausa: por que o tempo é mais longo do que no Nook HD +, embora a Nota 2 tenha um processador mais rápido? A resposta: modo de economia de energia. No Nook, foi desabilitado, na Nota 2 - habilitado. Decidiu testar com o modo de economia de energia desabilitado (como com ativado, também limita a velocidade do processador):

Samsung Galaxy Note 2 - ARM (Android 4.1.1), economia de energia desativada

Java: tempo total total (5 execuções): 7153 ms, com total de leitura de arquivo: 7459 ms

C #: Grande tempo total (5 execuções): 6906 ms, com total de leitura de arquivo: 7070 ms

Agora, surpreendentemente, o C # é um pouco mais rápido que o Java no processador ARM também. Grande melhoria!

Editar 12 de julho de 2013

Nós todos sabemos que nada supera o código nativo para velocidade, e eu não estava satisfeito com o desempenho do meu divisor de sentenças em Java ou C #, particularmente que eu preciso melhorá-lo (e assim torná-lo ainda mais lento). Decidiu reescrevê-lo em C ++. Aqui está um pequeno (ou seja, um conjunto menor de arquivos do que testes anteriores, por outras razões) comparação da velocidade de nativo vs. Java no meu Galaxy Note 2, com o modo de economia de energia desabilitado:

Java: tempo total total (5 execuções): 3292 ms, com total de leitura de arquivo: 3454 ms

Polegar nativo: tempo total total (5 execuções): 537 ms, com total de leitura de arquivo: 657 ms

Braço nativo: tempo total total (5 execuções): 458 ms, com total de leitura de arquivo: 587 ms

Parece que para o meu teste em particular, o código nativo é 6 a 7 vezes mais rápido que o Java. Ressalva: não poderia usar a classe std :: regex no Android, então tive que escrever minhas próprias rotinas especializadas procurando por quebras de parágrafos ou tags html. Meus testes iniciais do mesmo código em um PC usando regex foram cerca de 4 a 5 vezes mais rápidos que o Java.

Ufa! Acordando a memória bruta com os ponteiros char * ou wchar * novamente, eu imediatamente me senti 20 anos mais jovem! :)

Editar 15 de julho de 2013

(Por favor, veja abaixo, com edições de 30/07/2013, para resultados muito melhores com Dot42)

Com alguma dificuldade, eu consegui portar meus testes C # para Dot42 (versão 1.0.1.71 beta), outra plataforma C # para o Android. Resultados preliminares mostram que o código Dot42 é cerca de 3x (3 vezes) mais lento que o Xamarin C # (v. 4.7.11), em um emulador Intel Android. Um problema é que a classe System.Text.RegularExpressions no Dot42 não tem a função Split () que usei nos testes Xamarin, então usei a classe Java.Util.Regex, e Java.Util.Regex.Pattern.Split () , então neste lugar em particular no código, existe essa pequena diferença. Não deve ser um grande problema embora. O Dot42 é compilado para o código Dalvik (DEX), portanto, ele coopera com o Java no Android nativamente, não precisa de interoperabilidade dispendiosa de C # para Java como o Xamarin.

Apenas para comparação, eu também executo o teste em dispositivos ARM - aqui o código Dot42 é "apenas" 2x mais lento que o Xamarin C #. Aqui estão meus resultados:

HTC Nexus One Android 2.3.7 (ARM)

Java: tempo total total (5 execuções): 12187 ms, com total de leituras: 13200 ms

Xamarin C #: tempo total total (5 execuções): 13935 ms, com total de leitura de arquivos: 14465 ms

Dot42 C #: tempo total total (5 execuções): 26000 ms, com total de leituras: 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: tempo total total (5 execuções): 6895 ms, com total de leitura de arquivo: 7275 ms

Xamarin C #: tempo total total (5 execuções): 6466 ms, com total de leitura de arquivo: 6720 ms

Dot42 C #: tempo total total (5 execuções): 11185 ms, com total de leituras: 11843 ms

Emulador Intel, Android 4.2 (x86)

Java: tempo total total (5 execuções): 2389 ms, com total de leitura de arquivos: 2770 ms

Xamarin C #: tempo total total (5 execuções): 1748 ms, com total de leituras: 1933 ms

Dot42 C #: tempo total total (5 execuções): 5150 ms, com total de leitura de arquivos: 5459 ms

Para mim, também foi interessante notar que o Xamarin C # é um pouco mais rápido que o Java em um dispositivo ARM mais novo e um pouco mais lento no antigo Nexus One. Se alguém quiser executar esses testes também, informe-nos e atualizarei as fontes no GitHub. Seria particularmente interessante ver os resultados de um dispositivo Android real com processador Intel.

Atualização 26/07/2013

Apenas uma atualização rápida, re-compilada por aplicativos de benchmark com o último Xamarin.Android 4.8, e também com a atualização dot2 1.0.1.72 lançada hoje - sem alterações significativas dos resultados relatados anteriormente.

Atualização em 30/07/2013 - melhores resultados para dot42

Re-testado Dot42 com Robert's (de fabricantes de dot42) porta do meu código Java para C #. Em minha porta C # feita inicialmente para Xamarin, substituí algumas classes nativas de Java, como ListArray, com List nativa para C #, etc. Robert não tinha meu código fonte Dot42, então ele o portou novamente a partir de Java e usou classes Java originais em Esses lugares, o que beneficia Dot42, eu acho que é executado em Dalvik VM, como Java, e não em Mono, como Xamarin. Agora os resultados do Dot42 são muito melhores. Aqui está um log do meu teste:

30/07/2013 - Dot42 testa com mais classes Java no Dot42 C #

Emulador Intel, Android 4.2

Dot42, o código de Greg usando StringBuilder.Replace () (como em Xamarin):
Grande tempo total (5 execuções): 3646 ms, com total de leitura de arquivo: 3830 ms

Dot42, o código de Greg usando String.Replace () (como no código de Java e Robert):
Grande tempo total (5 execuções): 3027 ms, com total de leitura de arquivo: 3206 ms

Dot42, o código de Robert:
Grande tempo total (5 execuções): 1781 ms, com total de leitura de arquivo: 1999 ms

Xamarin:
Grande tempo total (5 execuções): 1373 ms, com total de leitura de arquivo: 1505 ms

Java:
Tempo total total (5 execuções): 1841 ms, com total de leituras: 2044 ms

ARM, Samsung Galaxy Note 2, economia de energia, Android 4.1.1

Dot42, o código de Greg usando StringBuilder.Replace () (como em Xamarin):
Grande tempo total (5 execuções): 10875 ms, com total de leitura de arquivo: 11280 ms

Dot42, o código de Greg usando String.Replace () (como no código de Java e Robert):
Grande tempo total (5 execuções): 9710 ms, com total de leitura de arquivo: 10097 ms

Dot42, o código de Robert:
Grande tempo total (5 execuções): 6279 ms, com total de leitura de arquivos: 6622 ms

Xamarin:
Grande tempo total (5 execuções): 6201 ms, com total de leitura de arquivo: 6476 ms

Java:
Grande tempo total (5 execuções): 7141 ms, com total de leitura de arquivo: 7479 ms

Eu ainda acho que Dot42 tem um longo caminho a percorrer. Ter classes semelhantes a Java (por exemplo, ArrayList) e um bom desempenho com elas tornaria o código de portabilidade de Java para C # um pouco mais fácil. No entanto, isso é algo que eu provavelmente não faria muito. Eu prefiro querer usar o código C # existente (bibliotecas etc.), que usará classes C # nativas (por exemplo, List), e que funcionará lentamente com o código atual dot42, e muito bem com Xamarin.

Greg


Aqui estão algumas informações que encontrei em outro teste entre as soluções nativa, Xamarin e Xamarin.Forms (os testes também incluem desempenhos iOS) nos dois dispositivos a seguir:

Samsung Galaxy A7 : Versão do sistema operacional Android: 6.0 Unidade de processamento central: Octa-core 1.9 GHz Cortex-A53 RAM: 3GB Resolução da tela: 1920 × 1080

iPhone 6s : Versão iOS: 10.3.3 Unidade de processamento central: Twister RAM dual-core 1,84 GHz: 2 GB Resolução da tela: 1334 × 750

A comparação é feita em alguns recursos comuns, cada um com seu próprio aplicativo:

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

Cada teste é repetido várias vezes, os gráficos mostram os resultados médios.

Olá Mundo

API de descanso

Conjunto de testes destinados a medir o tempo que o aplicativo leva para enviar uma solicitação por meio da API REST e receber a resposta de volta sem mais processamento de dados, usando a API OpenWeatherMap.

Operações JSON Testes feitos usando a estrutura Newtonsoft Json.net para serializar e desserializar objetos JSON em todos os aplicativos Xamarin. Serialização e desserialização do Android nativo testadas usando duas bibliotecas Java: Jackson e GSON.

Duas execuções são feitas, uma primeira a partir do zero e uma segunda com informações e operações em cache

Primeira corrida :

(Operações iOS JSON nativas estão acabando com esse teste, e Xamarin se junta a ele no segundo)

Operações Fotográficas

Primeiro carregue em imagens com três resoluções diferentes:

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

Algo parecia inseguro sobre os resultados do Xamarin.Forms para este teste, por isso não está incluído no gráfico.

Operações SQLite

Duas operações testadas:

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

Com bancos de dados com 10.000 registros. Todas as operações foram processadas internamente nos dispositivos.

O Xamarin Native (Xamarin.iOS / Xamarin.Android) mostra-se como boas alternativas ao código nativo, enquanto o Xamarin.Forms parece lento em muitos casos, mas pode ser uma solução muito boa para desenvolver aplicações realmente simples rapidamente.

O teste completo vem desta fonte:

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

Obrigado por me dar as explicações para melhorar a minha resposta, espero que isso ajude um pouco :)


São testes bastante antigos, mas podem ser relevantes: https://github.com/EgorBo/Xamarin.Android-vs-Java

Teste aritmético

Coleções, genéricos, tipos de valor personalizados

Trabalhando com strings

UPD: novos dados com o Google Pixel 2 (obrigado yousha-aleayoub )


Sim, a máquina virtual Mono de Xamarin é mais impressionante do que a Dalvik do Google usada no Android. Eu testei-o com HTC Flyer e Acer Iconia Tab comprimidos para comparar a porta C # do Android através do Mono contra o Java Dalvik, com a implementação do Android c # bem e verdadeiramente o Dalvik baseado em Java.






dot42