Я сталкивался с утверждениями Xamarin о том, что их реализация Mono на Android и их приложения, скомпилированные на C #, работают быстрее, чем код Java. Кто-нибудь выполнил реальные тесты на очень похожих кодах Java и C # на разных платформах Android, чтобы проверить такие утверждения, мог опубликовать код и результаты?
Добавлено 18 июня 2013 г.
Так как ответа не было и не удалось найти такие тесты, сделанные другими, я решил провести свои собственные тесты. К сожалению, мой вопрос остается «заблокированным», поэтому я не могу опубликовать его в качестве ответа, а только отредактировать вопрос. Пожалуйста, проголосуйте, чтобы снова открыть этот вопрос. Для C # я использовал Xamarin.Android Ver. 4.7.09001 (бета). Исходный код, все данные, которые я использовал для тестирования и скомпилированные пакеты APK, находятся на GitHub:
Java: https://github.com/gregko/TtsSetup_Java
C #: https://github.com/gregko/TtsSetup_C_sharp
Если кто-то захочет повторить мои тесты на других устройствах или эмуляторах, мне будет интересно узнать и результаты.
Результаты моего тестирования
Я перенес свой класс экстрактора предложений в C # (из моего приложения @Voice Aloud Reader) и провел несколько тестов для 10 файлов HTML на английском, русском, французском, польском и чешском языках. Каждый запуск был выполнен 5 раз для всех 10 файлов, и общее время для 3 различных устройств и одного эмулятора опубликовано ниже. Я тестировал только сборки "Release", без включенной отладки.
HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM
Java: общее общее время (5 запусков): 12361 мс, общее время чтения файла: 13304 мс
C #: общее общее время (5 запусков): 17504 мс, общее чтение файла: 17956 мс
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - ПЗУ CyanogenMod
Java: общее общее время (5 запусков): 8947 мс, общее время чтения файла: 9186 мс
C #: общее общее время (5 запусков): 9884 мс, общее время чтения файла: 10247 мс
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM
Java: общее общее время (5 запусков): 9742 мс, общее время чтения файла: 10111 мс
C #: общее общее время (5 запусков): 10459 мс, общее чтение файла: 10696 мс
Эмулятор - Intel (Android 4.2, API 17)
Java: общее общее время (5 запусков): 2699 мс, общее время чтения файла: 3127 мс
C #: общее общее время (5 запусков): 2049 мс, общее чтение файла: 2182 мс
Эмулятор - Intel (Android 2.3.7, API 10)
Java: общее общее время (5 запусков): 2992 мс, общее чтение файла: 3591 мс
C #: общее общее время (5 запусков): 2049 мс, общее чтение файла: 2257 мс
Эмулятор - Arm (Android 4.0.4, API 15)
Java: общее общее время (5 запусков): 41751 мс, общее время чтения файла: 43866 мс
C #: общее общее время (5 запусков): 44136 мс, общее чтение файла: 45109 мс
Краткое обсуждение
Мой тестовый код содержит в основном анализ текста, замену и поиск в Regex, возможно, для другого кода (например, больше числовых операций) результаты будут другими. На всех устройствах с процессорами ARM Java работала лучше, чем код Xamarin C #. Самая большая разница была под Android 2.3, где код C # работал на ок. 70% скорости Java.
В эмуляторе Intel (с технологией Intel HAX эмулятор работает в режиме быстрого виртуального выхода) код Xamarin C # выполняет мой пример кода намного быстрее, чем Java - примерно в 1,35 раза быстрее. Может быть, код и библиотеки виртуальной машины Mono намного лучше оптимизированы для Intel, чем для ARM?
Редактировать 8 июля 2013 г.
Я только что установил эмулятор Android Genymotion, который работает в Oracle VirtualBox, и снова этот использует собственный процессор Intel, а не процессор ARM. Как и в случае с эмулятором Intel HAX, снова C # работает здесь намного быстрее. Вот мои результаты:
Эмулятор Genymotion - Intel (Android 4.1.1, API 16)
Java: общее общее время (5 запусков): 2069 мс, общее время чтения файла: 2248 мс
C #: общее общее время (5 запусков): 1543 мс, общее чтение файла: 1642 мс
Затем я заметил, что появилось обновление для бета-версии Xamarin.Android, версия 4.7.11, с примечаниями к выпуску, в которых упоминались также некоторые изменения во время выполнения Mono. Решил быстро протестировать некоторые устройства ARM, и большой сюрприз - улучшилось число C #:
BN Nook XD +, ARM (Android 4.0)
Java: общее общее время (5 запусков): 8103 мс, общее время чтения файла: 8569 мс
C #: общее общее время (5 запусков): 7951 мс, общее чтение файла: 8161 мс
Вот Это Да! C # теперь лучше, чем Java? Решил повторить тест на моем Galaxy Note 2:
Samsung Galaxy Note 2 - ARM (Android 4.1.1)
Java: общее общее время (5 запусков): 9675 мс, общее чтение файла: 10028 мс
C #: общее общее время (5 запусков): 9911 мс, с общим чтением файла: 10104 мс
Здесь C # кажется немного медленнее, но эти цифры дали мне паузу: почему время длиннее, чем на Nook HD +, хотя Note 2 имеет более быстрый процессор? Ответ: режим энергосбережения. На Nook он был отключен, на Note 2 - включен. Решили протестировать с отключенным режимом энергосбережения (как и при включенном, он также ограничивает скорость процессора):
Samsung Galaxy Note 2 - ARM (Android 4.1.1), энергосбережение отключено
Java: общее общее время (5 запусков): 7153 мс, общее время чтения файла: 7459 мс
C #: общее общее время (5 запусков): 6906 мс, общее чтение файла: 7070 мс
Теперь, что удивительно, C # немного быстрее, чем Java на процессоре ARM. Большое улучшение!
Изменить 12 июля 2013 г.
Все мы знаем, что ничто не сравнится с быстродействием нативного кода, и я не был удовлетворен производительностью моего сплиттера предложений в Java или C #, особенно в том, что мне нужно его улучшить (и, следовательно, сделать его еще медленнее). Решил переписать это на C ++. Вот небольшое (т. Е. Меньший набор файлов, чем предыдущие тесты, по другим причинам) сравнение скорости нативной и Java на моей Galaxy Note 2 с отключенным режимом энергосбережения:
Java: общее общее время (5 запусков): 3292 мс, общее чтение файла: 3454 мс
Собственный большой палец: общее общее время (5 запусков): 537 мс, общее время чтения файла: 657 мс
Родная рука: Общее общее время (5 запусков): 458 мс, с общим чтением файла: 587 мс
Похоже, для моего конкретного теста нативный код работает в 6-7 раз быстрее, чем Java. Предостережение: не могу использовать класс std :: regex на Android, поэтому пришлось написать свои собственные специализированные процедуры для поиска разрывов абзацев или HTML-тегов. Мои начальные тесты того же кода на ПК с использованием регулярных выражений, были примерно в 4-5 раз быстрее, чем Java.
Уф! Пробуждая сырую память с помощью указателей char * или wchar *, я сразу почувствовал себя на 20 лет моложе! :)
Редактировать 15 июля 2013 г.
(Пожалуйста, смотрите ниже, с изменениями от 30.07.2013, для гораздо лучших результатов с Dot42)
С некоторым трудом мне удалось перенести свои тесты C # на Dot42 (версия 1.0.1.71 бета), еще одну платформу C # для Android. Предварительные результаты показывают, что код Dot42 примерно в 3 раза (в 3 раза) медленнее, чем Xamarin C # (v. 4.7.11), на эмуляторе Intel Android. Одна из проблем заключается в том, что класс System.Text.RegularExpressions в Dot42 не имеет функции Split (), которую я использовал в тестах Xamarin, поэтому вместо этого я использовал класс Java.Util.Regex и Java.Util.Regex.Pattern.Split (). Таким образом, в этом конкретном месте кода есть небольшая разница. Не должно быть большой проблемой, хотя. Dot42 компилируется в код Dalvik (DEX), поэтому он изначально взаимодействует с Java на Android, не требует дорогостоящего взаимодействия с C # до Java, такого как Xamarin.
Для сравнения, я также запускаю тест на устройствах ARM - здесь код Dot42 "всего лишь" в 2 раза медленнее, чем Xamarin C #. Вот мои результаты:
HTC Nexus One Android 2.3.7 (ARM)
Java: общее общее время (5 запусков): 12187 мс, общее время чтения файла: 13200 мс
Xamarin C #: общее общее время (5 прогонов): 13935 мс, с общим чтением файла: 14465 мс
Dot42 C #: общее общее время (5 запусков): 26000 мс, общее чтение файла: 27168 мс
Samsung Galaxy Note 2, Android 4.1.1 (ARM)
Java: общее время (5 запусков): 6895 мс, общее время чтения файла: 7275 мс
Xamarin C #: общее общее время (5 запусков): 6466 мс, общее время чтения файла: 6720 мс
Dot42 C #: общее общее время (5 запусков): 11185 мс, общее чтение файла: 11843 мс
Эмулятор Intel, Android 4.2 (x86)
Java: общее общее время (5 запусков): 2389 мс, общее время чтения файла: 2770 мс
Xamarin C #: общее общее время (5 запусков): 1748 мс, общее чтение файла: 1933 мс
Dot42 C #: общее общее время (5 запусков): 5150 мс, общее чтение файла: 5459 мс
Мне было также интересно отметить, что Xamarin C # немного быстрее Java на более новом устройстве ARM и немного медленнее на старом Nexus One. Если кто-то также хотел бы запустить эти тесты, пожалуйста, дайте мне знать, и я обновлю исходники на GitHub. Было бы особенно интересно увидеть результаты реального устройства Android с процессором Intel.
Обновление 26.07.2013
Просто быстрое обновление, перекомпилированное эталонными приложениями с последним Xamarin.Android 4.8, а также с вышедшим сегодня обновлением dot42 1.0.1.72 - никаких существенных изменений по сравнению с результатами, о которых сообщалось ранее.
Обновление 30.07.2013 - лучшие результаты для dot42
Перепроверено Dot42 с портом Роберта (от создателей dot42) моего Java-кода на C #. В моем C # -порте, изначально созданном для Xamarin, я заменил некоторые собственные классы Java, такие как ListArray, на класс List, родной для C # и т. Д. У Роберта не было моего исходного кода Dot42, поэтому он снова перенес его из Java и использовал оригинальные классы Java в такие места, которые приносят пользу Dot42, я думаю, потому что он работает в Dalvik VM, как Java, а не в Mono, как Xamarin. Теперь результаты Dot42 намного лучше. Вот журнал из моего тестирования:
30.07.2013 - Тесты Dot42 с большим количеством классов Java в Dot42 C #
Эмулятор Intel, Android 4.2
Dot42, код Грега с использованием StringBuilder.Replace () (как в Xamarin):
общее общее время (5 запусков): 3646 мс, с общим чтением файла: 3830 мсDot42, код Грега с использованием String.Replace () (как в коде Java и Роберта):
общее общее время (5 запусков): 3027 мс, с общим чтением файла: 3206 мсDot42, код Роберта:
общее время (5 прогонов): 1781 мс, общее чтение файла: 1999 мсXamarin:
общее общее время (5 запусков): 1373 мс, общее время чтения файла: 1505 мсJava:
общее общее время (5 запусков): 1841 мс, общее время чтения файла: 2044 мсARM, Samsung Galaxy Note 2, энергосбережение выключено, Android 4.1.1
Dot42, код Грега с использованием StringBuilder.Replace () (как в Xamarin):
общее общее время (5 прогонов): 10875 мс, с общим чтением файла: 11280 мсDot42, код Грега с использованием String.Replace () (как в коде Java и Роберта):
общее общее время (5 запусков): 9710 мс, с общим чтением файла: 10097 мсDot42, код Роберта:
общее время (5 прогонов): 6279 мс, общее чтение файла: 6622 мсXamarin:
общее общее время (5 запусков): 6201 мс, общее время чтения файла: 6476 мсJava:
общее общее время (5 запусков): 7141 мс, общее чтение файла: 7479 мс
Я все еще думаю, что Dot42 еще далеко. Наличие Java-подобных классов (например, ArrayList) и хорошая производительность с ними сделают перенос кода с Java на C # немного проще. Тем не менее, это то, что я вряд ли буду делать много. Я бы предпочел использовать существующий код C # (библиотеки и т. Д.), Который будет использовать собственные классы C # (например, List), и который будет работать медленно с текущим кодом dot42 и очень хорошо с Xamarin.
Greg
Ответы:
Да, виртуальная машина Xamarin Mono более впечатляет, чем Google Dalvik, используемый в Android. Я протестировал его на планшетах HTC Flyer и Acer Iconia Tab, чтобы сравнить порт C # Android через Mono с Java Dalvik, с реализацией C # в Android и поистине беспокоящей Dalvik на основе Java.
источник
https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976#.kfbauchtz
Надеюсь, эта информация поможет.
источник
Недавно мы исследовали использование Xamarin для приложения. Мы использовали код C #, который мы уже написали для версии нашего приложения для Windows RT. Некоторые конкретные детали должны были быть переписаны для версии Android.
Мы обнаружили, что ввод-вывод в Xamarin C # примерно в 2 раза медленнее, чем в Java. Наше приложение сильно связано с вводом / выводом. Мы еще не обнаружили причину этого, но в настоящий момент мы предполагаем, что это связано с маршалингом. Хотя мы пытаемся оставаться внутри ВМ Mono большую часть времени, мы не знаем, как Mono фактически обращается к диску.
Это также говорит о том, что наш код C # использует SQLite.NET ( https://github.com/praeclarum/sqlite-net ). Идентичные выборки с использованием кода SQLite.NET также в 2 раза медленнее, чем с помощью обёртки Android SQLite для Android. После просмотра исходного кода, он, кажется, связывается непосредственно с C .dll, поэтому я не знаю, почему он намного медленнее. Одна из возможностей заключается в том, что маршалинг строк из нативного в Java может быть быстрее на Android, чем нативный на C # на Xamarin.
источник
Это еще один обновленный пост в блоге, которым я хотел бы поделиться с вами . Он сравнивает Xamarin с нативным кодом и Cordova на IO и Android.
Короче говоря, Xamarin работает иногда лучше, чем собственный код. Он проверил размер приложения, время загрузки, загрузку списка из службы Azure и вычисление простых чисел.
Наслаждайтесь!
Изменить: я обновил мертвую ссылку, и я заметил, что есть часть 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 RAM: 2 ГБ Разрешение экрана: 1334 × 750
Сравнение проводится по нескольким общим характеристикам, каждое из которых имеет свое приложение:
Каждый тест повторяется несколько раз, графики показывают средние результаты.
Привет мир
API отдыха
Набор тестов, предназначенных для измерения времени, которое требуется приложению для отправки запроса через REST API и получения ответа без дальнейшей обработки данных с использованием API OpenWeatherMap.
Операции JSON Тесты, выполненные с использованием инфраструктуры Newtonsoft Json.net, для сериализации и десериализации объектов JSON во всех приложениях Xamarin. Нативная сериализация и десериализация Android протестирована с использованием двух библиотек Java: Jackson и GSON.
Выполняется два прогона: первый с нуля, а второй с кэшированной информацией и операциями.
Первый забег :
(Кстати, собственный тест JSON Operations для iOS убивает этот тест, и Xamarin присоединяется к нему во втором)
Операции с фотографиями
Сначала загрузите изображения с тремя различными разрешениями:
Что-то казалось неуверенным в результатах Xamarin.Forms для этого теста, поэтому он не включен в график.
Операции SQLite
Проверено две операции:
С базами данных, имеющими 10000 записей. Все операции были обработаны внутри устройства.
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/
Спасибо, что дали мне объяснения, чтобы улучшить мой ответ, надеюсь, это немного поможет :)
источник
Представление
Производительность - это смутное слово, если вы не определяете, что вы подразумеваете под производительностью, если это просто производительность вычислений, Xamarin может быть быстрее, чем Java, в зависимости от характера вычислений.
Android изначально поставляется с несколькими формами для выполнения кода в:
Совершенно очевидно, что при выполнении кода, чем более нативное решение, тем быстрее оно будет. Язык во время выполнения никогда не превзойдет язык, который напрямую работает на процессоре.
Но с другой стороны, если вы хотите измерить производительность в реальных условиях, Java будет propbaby быстрее, чем Xamarin.
Xamarin и почему это может быть медленнее
При сравнении Xamarin с простыми старыми приложениями Java производительность Xamarin вполне может быть выше, так как она может быть ниже.
В реальных примерах приложения Xamarin, скорее всего, будут работать медленнее, чем приложения Java, поскольку многие вызовы Android / Java (системные) необходимо делегировать во время выполнения Xamarin и из него, используя так называемые привязки.
Есть несколько разных типов привязок, которые важно знать:
Привязки с точки зрения производительности очень и очень дороги. Вызов метода C ++ из Java добавляет огромные издержки во время вызова, вызов метода C ++ изнутри C ++ во много-много раз быстрее.
Но не только звонки JNI являются дорогостоящими, так и звонки в и из MCW и ACW. Реальные приложения Xamarin делают много вызовов, используя привязки, и из-за этого использование Xamarin в реальном мире может быть (и будет в целом) медленнее, чем обычное старое Java-приложение. Однако в зависимости от того, как было разработано приложение Xamarin, очень вероятно, что пользователь даже не заметит разницы.
TLDR / Вывод: Xamarin необходимо использовать все виды привязок, которые являются дорогостоящими.
источник
Это довольно старые тесты, но они могут быть актуальны: https://github.com/EgorBo/Xamarin.Android-vs-Java
Арифметический тест
Коллекции, дженерики, пользовательские типы значений
Работа со строками
UPD: новые данные с Google Pixel 2 (спасибо yousha-aleayoub )
источник