У кого-нибудь есть тесты (код и результаты), сравнивающие производительность приложений Android, написанных на Xamarin C # и Java?

452

Я столкнулся с тем, что Xamarin утверждает, что их реализация Mono на Android и их скомпилированные приложения на С# быстрее, чем Java-код. Кто-нибудь выполнял фактические тесты на очень похожие Java и С# -код на разных платформах Android для проверки таких претензий, мог бы опубликовать код и результаты?

Добавлено 18 июня 2013 г.

Поскольку ответа не было и не удалось найти такие тесты, сделанные другими, решил сделать мои собственные тесты. К сожалению, мой вопрос остается "заблокирован", поэтому я не могу опубликовать это как ответ, только отредактируйте вопрос. Пожалуйста, проголосуйте, чтобы повторно открыть этот вопрос. Для С# я использовал Xamarin.Android ver. 4.7.09001 (бета). Исходный код, все данные, которые я использовал для тестирования, и скомпилированные пакеты APK находятся в GitHub:

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

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

Если кто-то захочет повторить мои тесты на других устройствах или эмуляторах, мне было бы интересно также изучить результаты.

Результаты моего тестирования

Я портировал класс экстрактора предложения на С# (из моего приложения @Voice Aloud Reader) и запускал некоторые тесты на 10 html файлах на английском, русском, французском, польском и чешском языках. Каждый прогон выполнялся 5 раз на всех 10 файлах, а общее время для трех разных устройств и одного эмулятора размещено ниже. Я тестировал только "Release", но без отладки.

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

Java: общее время (5 прогонов): 12361 мс, при чтении файла: 13304 мс

С#: общее время (5 прогонов): 17504 мс, при чтении файла: 17956 мс

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

Java: общее время (5 прогонов): 8947 мс, с общим количеством файлов: 9186 мс

С#: общее время (5 прогонов): 9884 мс, с общим объемом файла: 10247 мс

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

Java: общее время (5 прогонов): 9742 мс, при чтении файла: 10111 мс

С#: общее время (5 пробегов): 10459 мс, с общим количеством файлов: 10696 мс

Эмулятор - Intel (Android 4.2, API 17)

Java: общее время (5 прогонов): 2699 мс, при чтении файла: 3127 мс

С#: общее общее время (5 прогонов): 2049 мс, при чтении файла: 2182 мс

Эмулятор - Intel (Android 2.3.7, API 10)

Java: общее время (5 прогонов): 2992 мс, при чтении файла: 3591 мс

С#: общее время (5 прогонов): 2049 мс, с общим объемом файла: 2257 мс

Emulator - Arm (Android 4.0.4, API 15)

Java: общее время (5 прогонов): 41751 мс, при чтении файла: 43866 мс

С#: общее время (5 прогонов): 44136 мс, при чтении файла: 45109 мс

Краткое обсуждение

Мой тестовый код содержит в основном текстовое разбор, замену и поиск в регулярном выражении, возможно, для другого кода (например, более числовые операции) результаты будут разными. На всех устройствах с ARM-процессорами Java работает лучше, чем Xamarin С#. Самая большая разница была в Android 2.3, где код С# запускался прибл. 70% скорости Java.

В эмуляторе Intel (с технологией Intel HAX, эмулятор работает в режиме быстрого virt), код Xamarin С# работает с моим примером кода намного быстрее, чем Java - примерно в 1,35 раза быстрее. Может ли Mono виртуальный машинный код и библиотеки гораздо лучше оптимизированы для Intel, чем на ARM?

Изменить 8 июля 2013 г.

Я только что установил эмулятор Genymotion Android, который работает в Oracle VirtualBox, и снова этот использует собственный процессор Intel, а не эмулятор ARM-процессора. Как и в случае с эмулятором Intel HAX, снова С# работает здесь намного быстрее. Вот мои результаты:

Эмулятор Genymotion - Intel (Android 4.1.1, API 16)

Java: Общее общее время (5 пробегов): 2069 мс, при чтении файла: 2248 мс

С#: Общее общее время (5 пробегов): 1543 мс, при чтении файла: 1642 мс

Затем я заметил, что было обновлено бета-версия Xamarin.Android, версия 4.7.11, с примечаниями к выпуску, в которых упоминаются некоторые изменения в среде исполнения Mono. Решили быстро протестировать некоторые устройства ARM и большой сюрприз - улучшены номера С#:

BN Nook XD +, ARM (Android 4.0)

Java: общее время (5 прогонов): 8103 мс, с общим объемом файла: 8569 мс

С#: общее время (5 прогонов): 7951 мс, с общим количеством файлов: 8161 мс

Ничего себе! С# теперь лучше, чем Java? Решил повторить тест на моей Галактике Примечание 2:

Samsung Galaxy Note 2 - ARM (Android 4.1.1)

Java: общее время (5 прогонов): 9675 мс, общее число файлов: 10028 мс

С#: общее время (5 прогонов): 9911 мс, при чтении файла: 10104 мс

Здесь С# выглядит немного медленнее, но эти цифры дали мне паузу: почему время больше, чем на Nook HD +, хотя Note 2 имеет более быстрый процессор? Ответ: режим энергосбережения. На Nook он отключен, включен Примечание 2. Решено протестировать с отключенным режимом энергосбережения (как при включенном, оно также ограничивает скорость процессора):

Samsung Galaxy Note 2 - ARM (Android 4.1.1), энергосбережение отключено

Java: общее время (5 прогонов): 7153 мс, при чтении файла: 7459 мс

С#: общее время (5 прогонов): 6906 мс, с общим количеством файлов: 7070 мс

Теперь, что удивительно, С# немного быстрее, чем Java на процессоре ARM. Большое улучшение!

Редактировать 12 июля 2013 г.

Мы все знаем, что ничто не сравнится с собственным кодом для скорости, и меня не устраивало производительность моего разделителя предложений в Java или С#, особенно, что мне нужно его улучшить (и тем самым сделать его еще медленнее). Решил переписать его на С++. Вот небольшой (т.е. Меньший набор файлов, чем предыдущие тесты, по другим причинам) сравнение скорости родной и Java на моей Galaxy Note 2 с отключенным режимом энергосбережения:

Java: Общее общее время (5 пробегов): 3292 мс, при чтении файла: 3454 мс

Нативный палец: Общее общее время (5 пробегов): 537 мс, при чтении файла: 657 мс

Родная рука: Общее общее время (5 пробегов): 458 мс, при чтении файла: 587 мс

Похоже, что для моего конкретного теста собственный код в 6-7 раз быстрее, чем Java. Caveat: не мог использовать класс std:: regex на Android, поэтому мне пришлось писать собственные специализированные процедуры поиска абзацев breaks или html-тегов. Мои начальные тесты одного и того же кода на ПК с использованием regex были примерно в 4-5 раз быстрее, чем Java.

Уф! Пробуждая необработанную память с помощью указателей char * или wchar *, я мгновенно почувствовал себя на 20 лет моложе!:)

Редактировать 15 июля 2013 г.

(см. ниже, с изменениями от 7/30/2013, для получения гораздо лучших результатов с Dot42)

С некоторым трудом мне удалось перенести мои тесты С# на Dot42 (версия 1.0.1.71 beta), еще одна платформа С# для Android. Предварительные результаты показывают, что код Dot42 примерно в 3 раза (3 раза) медленнее, чем Xamarin С# (версия 4.7.11), на эмуляторе Intel Android. Одна из проблем заключается в том, что класс System.Text.RegularExpressions в Dot42 не имеет функции Split(), которую я использовал в тестах Xamarin, поэтому вместо этого я использовал класс Java.Util.Regex и Java.Util.Regex.Pattern.Split(), поэтому в этом конкретном месте в коде есть эта небольшая разница. Однако не должно быть большой проблемой. Dot42 компилируется в код Dalvik (DEX), поэтому он взаимодействует с Java на Android изначально, не требует дорогостоящего взаимодействия с С# на Java, например Xamarin.

Просто для сравнения, я также запускаю тест на устройствах ARM - здесь код Dot42 "только" 2x медленнее, чем Xamarin С#. Вот мои результаты:

HTC Nexus One Android 2.3.7 (ARM)

Java: общее время (5 прогонов): 12187 мс, при чтении файла: 13200 мс

Xamarin С#: общее время (5 пробегов): 13935 мс, при чтении файла: 14465 мс

Dot42 С#: общее время (5 прогонов): 26000 мс, с общим объемом файла: 27168 мс

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: общее время (5 прогонов): 6895 мс, при чтении файла: 7275 мс

Xamarin С#: общее время (5 пробегов): 6466 мс, с общим количеством файлов: 6720 мс

Dot42 С#: общее время (5 прогонов): 11185 мс, с общим объемом файла: 11843 мс

эмулятор Intel, Android 4.2 (x86)

Java: общее время (5 прогонов): 2389 мс, с общим объемом файла: 2770 мс

Xamarin С#: общее время (5 пробегов): 1748 мс, с общим количеством файлов: 1933 мс

Dot42 С#: общее время (5 прогонов): 5150 мс, с общим объемом файла: 5459 мс

Мне также было интересно отметить, что Xamarin С# немного быстрее, чем Java на более новом устройстве ARM, и немного медленнее на старом Nexus One. Если кто-то захочет также запустить эти тесты, сообщите мне, и я обновлю источники на GitHub. Было бы особенно интересно увидеть результаты с реального Android-устройства с процессором Intel.

Обновление 7/26/2013

Просто быстрое обновление, скомпилированное с помощью тестов с последними версиями Xamarin.Android 4.8, а также с выпуском dot42 1.0.1.72, выпущенным сегодня - никаких существенных изменений в результатах, о которых сообщалось ранее.

Обновление 7/30/2013 - лучшие результаты для dot42

Повторно протестировано Dot42 с Робертом (от производителей dot42) порт моего Java-кода до С#. В моем порт С#, первоначально сделанный для Xamarin, я заменил некоторые родные классы Java, такие как ListArray, с классом List, родным С# и т.д. У Robert не было моего исходного кода Dot42, поэтому он портировал его снова с Java и использовал оригинальные классы Java в такие места, которые приносят пользу Dot42, я думаю, потому что он работает в Dalvik VM, как Java, а не в Mono, как Xamarin. Теперь результаты Dot42 намного лучше. Вот журнал из моего тестирования:

7/30/2013 - тесты Dot42 с большим количеством классов Java в Dot42 С#

эмулятор Intel, Android 4.2

Dot42, Greg Code с помощью StringBuilder.Replace() (как в Xamarin):
Общее общее время (5 пробегов): 3646 мс, при чтении файла: 3830 мс

Dot42, Greg Code с использованием String.Replace() (как в коде Java и Robert):
Общее общее время (5 прогонов): 3027 мс, при чтении файла: 3206 мс

Dot42, Robert Код:
Общее общее время (5 пробегов): 1781 мс, при чтении файла: 1999 мс

Xamarin:
Общее общее время (5 пробегов): 1373 мс, при чтении файла: 1505 мс

Java:
Общее общее время (5 пробегов): 1841 мс, при чтении файла: 2044 мс

ARM, Samsung Galaxy Note 2, энергосбережение, Android 4.1.1

Dot42, Greg Code с помощью StringBuilder.Replace() (как в Xamarin):
Общее общее время (5 пробегов): 10875 мс, при чтении файла: 11280 мс

Dot42, Greg Code с использованием String.Replace() (как в коде Java и Robert):
Общее общее время (5 пробегов): 9710 мс, при чтении файла: 10097 мс

Dot42, Robert Код:
Общее общее время (5 пробегов): 6279 мс, при чтении файла: 6622 мс

Xamarin:
Общее общее время (5 пробегов): 6201 мс, при чтении файла: 6476 мс

Java:
Общее общее время (5 пробегов): 7141 мс, при чтении файла: 7479 мс

Я все еще думаю, что Dot42 имеет долгий путь. Наличие Java-подобных классов (например, ArrayList) и хорошая производительность с ними сделают код переноса с Java на С# немного легче. Тем не менее, это то, что я вряд ли буду делать много. Я бы предпочел использовать существующий код С# (библиотеки и т.д.), Который будет использовать собственные классы С# (например, List), и это будет медленно работать с текущим кодом dot42 и очень хорошо с Xamarin.

Грег

  • 5
    Режим отладки на Nexus 7 4.2.2 с некоторыми оптимизациями для строк и xamarin alpha 9: общее время: 3907 мс, с общим объемом чтения файла: 4016. Что означает «5 прогонов»?
  • 0
    Режим разблокировки на той же платформе: общее время: 2192 мс, общее чтение файла: 2279
Показать ещё 21 комментарий
Теги:
xamarin
dot42

7 ответов

56

Да, виртуальная машина Xamarin Mono более впечатляющая, чем Google Dalvik, используемая в Android. Я протестировал его с помощью HTC Flyer и планшетов Acer Iconia Tab, чтобы сравнить С# порт Android с помощью Mono против Java Dalvik, с реализацией С# для Android и, действительно, запуская Java-платформу Dalvik.

  • 3
    @PeterLawrey, пожалуйста, смотрите мое обновление вопроса. Я намереваюсь перенести некоторую часть моего реального Java-кода на C # и запустить тесты, а затем опубликовать их здесь - если они вновь откроют мой вопрос, так как Бдительные СО закрыли его почти сразу.
  • 1
    @PeterLawrey - я теперь проводил свои тесты и публиковал результаты в StackOverflow, но внутри самого Вопроса, поскольку он все еще остается "заблокированным" и не может опубликовать ответ. Если вы могли бы, пожалуйста, добавьте свой голос, чтобы вновь открыть вопрос. Результаты интересны, на ARM Java выигрывает, на Intel - C # код в Mono намного быстрее.
Показать ещё 9 комментариев
33
I came across this interesting post

https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz

Изображение 1058

Изображение 1059

Надеемся, что эта информация поможет.

30

Это еще один обновленный пост в блоге, который я хотел бы поделиться с вами. Он сравнивает Xamarin с родным кодом и Cordova как с IO, так и с Android.

В двух словах, Xamarin выполняет иногда лучше, чем собственный код. Он тестировал размер приложения, время загрузки, загрузку списка из службы Azure и вычисления простых чисел.

Наслаждайтесь!

Изменить: я обновил мертвую ссылку, и я заметил, что есть часть 2

27

Недавно мы исследовали использование Xamarin для приложения. Мы использовали код С#, который мы уже писали для версии нашего приложения Windows RT. Некоторые детали были переписаны для версии Android.

Мы обнаружили, что I/O в Xamarin С# примерно в 2 раза медленнее, чем Java. Наше приложение сильно связано с I/O. Мы еще не обнаружили причину этого, но на данный момент мы предполагаем, что это связано с маршалингом. Хотя мы стараемся оставаться внутри Mono VM большую часть времени, мы не знаем, как Mono фактически обращается к диску.

Также говорится, что наш С# -код использует SQLite.NET(https://github.com/praeclarum/sqlite-net). Идентичные выборки с использованием кода SQLite.NET также в 2 раза медленнее, чем использование оболочки Javaite SQLite. Посмотрев исходный код, он, похоже, напрямую связан с C.dll, поэтому я не знаю, почему он так медленнее. Одна из возможностей заключается в том, что маршалинг строк из native на Java может быть быстрее на Android, чем на С# на Xamarin.

  • 0
    Скорее всего, это также связано с «привязками», которые Ксамерин должен взаимодействовать с системой. Каждый системный вызов по умолчанию направляется в класс Java, но его необходимо делегировать виртуальной машине Mono, что занимает много времени. То же самое происходит и в обратном порядке. Я объяснил это немного больше в своем ответе: stackoverflow.com/a/46973819/1052697
2

Вот несколько сведений, которые я нашел в другом тесте между собственными решениями Xamarin и Xamarin.Forms(тесты также включают в себя производительность iOS) на двух следующих устройствах:

Samsung Galaxy A7:   Версия ОС Android: 6.0   Центральный процессор: Octa-core 1,9 ГГц Cortex-A53   Оперативная память: 3 ГБ   Разрешение экрана: 1920 × 1080

iPhone 6s:   Версия iOS: 10.3.3   Центральный процессор: двухъядерный 1,84 ГГц Twister   ОЗУ: 2 ГБ   Разрешение дисплея: 1334 × 750

Сравнение производится по нескольким общим функциям, каждый со своим приложением:

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

Каждый тест повторяется несколько раз, графики показывают средние результаты.


Hello World

Изображение 1060


API поддержки

Набор тестов, предназначенных для измерения времени, которое требуется, чтобы приложение отправляло запрос через REST API и получало ответ без дальнейшей обработки данных, используя API OpenWeatherMap.

Изображение 1061


Операции JSON Тесты, выполненные с использованием инфраструктуры Newtonsoft Json.net для сериализации и десериализации объектов JSON во всех приложениях Xamarin. Серийная сериализация и десериализация сериализации Android тестировались с использованием двух библиотек Java: Jackson и GSON.

Выполняются два прогона: первый с нуля и второй с кешированной информацией и операциями

Первый запуск:

Изображение 1062

Изображение 1063

(Native iOS JSON Operations убивает эту тестовую битву, а Xamarin присоединяется к ней во втором)

Изображение 1064

Изображение 1065


Операции с фотографиями

Сначала загрузите изображения с тремя различными разрешениями:

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

Изображение 1066

Изображение 1067

Что-то казалось неуверенным в результатах Xamarin.Forms для этого теста, поэтому он не включен в график.


Операции SQLite

Проверено две операции:

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

С базами данных, имеющими 10 000 записей. Все операции были обработаны внутри устройства.

Изображение 1068

Изображение 1069


Xamarin Native (Xamarin.iOS/Xamarin.Android) проявляют себя как довольно хорошие альтернативы родному коду, тогда как Xamarin.Forms во многих случаях кажется медленным, но это может быть действительно хорошим решением для разработки действительно простых приложений быстрее.

Полное тестирование исходит из этого источника:

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

Спасибо, что дали мне объяснения, чтобы усилить мой ответ, надеюсь, что это поможет немного:)

1

Производительность

Производительность - это неопределенное слово, если вы не определяете, что вы подразумеваете под действием производительности, если это простая вычислительная производительность Xamarin может быть быстрее, чем Java, в зависимости от характера вычисления.

Android nativly поставляется с форматами multipe для выполнения кода в:

  • RenderScript (CPU и GPU)
  • Java (SDK)
  • С++ (NDK)
  • OpenGL (GPU)

Совершенно очевидно, что при выполнении кода более естественным будет решение, тем быстрее оно будет. Язык, основанный на времени выполнения, никогда не будет бить язык, который непосредственно запускается на процессоре.

Но, с другой стороны, если вы хотите измерить реальную производительность использования Java, то propbaby будет быстрее, чем Xamarin.

Xamarin и почему он может быть медленнее

При сравнении Xamarin с обычными старыми Java-приложениями производительность может быть намного быстрее для Xamarin, поскольку она может быть медленнее.

В реальном мире приложения Xamarin, скорее всего, будут медленнее, чем Java-приложения, потому что многие вызовы на базе Android/Java (системные) необходимо делегировать и выполнять во время выполнения Xamarin с помощью так называемых привязок.

Существует несколько различных типов привязок, которые важно знать:

  • JNI (Java Native Interface): Связывание, используемое во многих приложениях Android для взаимодействия между Java-кодом (SDK) и собственным кодом С++ (NDK).
  • MCW (Managed Callable Wrappers): Связывание, доступное в Xamarin для интерфейса с управляемого кода С# на Java-код (время выполнения Android).
  • ACW (Android Callable Wrappers): Связывание, доступное в Xamarin для взаимодействия с кодом Java (время выполнения Android) с управляемым кодом С#.

Подробнее о MCW и ACW здесь: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

Привязки с точки зрения производительности очень дорогостоящие. Вызов метода С++ из Java добавляет огромные накладные расходы во время вызова, вызывая метод С++ из С++ во много раз быстрее.

Кто-то выполнил тест производительности, чтобы рассчитать, сколько операций Java в среднем связано с вызовом JNI: Каковы количественные накладные расходы на вызов JNI?

Но не только вызовы JNI являются дорогостоящими, поэтому звонки в MCW и ACW и обратно. Приложения Xamarin реального мира делают много звонков с использованием привязок, и из-за этого реального использования приложения Xamarin может быть (и будет в целом) медленнее обычного старого Java-приложения. Однако в зависимости от того, как было разработано приложение Xamarin, очень вероятно, что пользователь не заметит разницы.

TL;DR/Заключение: Xamarin необходимо использовать привязки al sorts, которые являются дорогостоящими.

Помимо привязок, есть много других факторов, связанных с реализацией реального мира, например: размер двоичного файла, загрузка приложения в память, операции ввода-вывода и многое другое. Сообщение в блоге, которое исследует некоторые из этих вещей, можно найти здесь: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms

1

Это довольно старые тесты, но могут быть релевантными: https://github.com/EgorBo/Xamarin.Android-vs-Java

Арифметический тест

Изображение 1070

Коллекции, дженерики, настраиваемые типы значений

Изображение 1071

Работа со строками

Изображение 1072

Ещё вопросы

Сообщество Overcoder
Наверх
Меню