Чтобы улучшить производительность приложения на Android, я начал постепенно переписывать критические участки кода с Java (SDK) на C++ (NDK).
Результат оказался сравним с тем, что я получил пару десятков лет назад, делая ассемблерные вставки в код турбопаскаля.
Я не ставлю перед собой задачу описать, как работать с Android NDK — у меня самого недостаточно опыта.
Кому интересно, стоит начать с этот ссылки.
Цель этой небольшой статьи — привести некоторые цифры, которые я получил эмпирическим путем, сравнивая время выполнения некоторых функций, написанных на Java, а затем переписанных на C++.
И возможно, эти цифры побудят кого-то более глубоко изучить этот вопрос.
Так как мое приложение связано с обработкой фотографий, то узкими местами были циклы обхода пикселей картинки и определенные действия над ними.
Тестировал на реальных устройствах - Nexus One и Nexus 7 (2012).
Результаты экспериментов (в мс) были сведены в таблицу:
Наложение слоев (режим «Яркость», цветной рисунок)
Нексус Один | Нексус 7 | ||
---|---|---|---|
SDK | НДК | SDK | НДК |
2563 | 120 | 4850 | 90 |
2122 | 100 | 4520 | 190 |
2162 | 110 | 4330 | 100 |
Наложение слоя (режим Color Dodge, одноцветный узор)
Нексус Один | Нексус 7 | ||
---|---|---|---|
SDK | НДК | SDK | НДК |
2673 | 30 | 5720 | 80 |
2572 | 20 | 6230 | 70 |
2573 | 20 | 6110 | 70 |
Наложение слоев с использованием градиента прозрачности
Нексус Один | Нексус 7 | ||
---|---|---|---|
SDK | НДК | SDK | НДК |
1301 | 321 | 3010 | 470 |
1221 | 330 | 2670 | 620 |
1211 | 300 | 2770 | 610 |
Как видите, результаты различаются на один, а то и два порядка.
Я специально привел цифры в абсолютных значениях, чтобы было видно реальное ускорение работы от использования NDK. Относительно скромные результаты последнего теста связаны с тем, что для расчета оверлея использовались стандартные функции библиотеки OpenCV, которые достаточно хорошо оптимизированы.
Соответственно, этот тест наглядно показывает реальное ускорение приложения в целом.
Кратко остановлюсь на использовании библиотеки OpenCV. Как я и ожидал, Java-часть библиотеки представляет собой обычную обертку над NDK. Тем не менее, описанные выше эксперименты я проводил на довольно тяжелых и долговечных алгоритмах — таких как поиск характерных точек на изображениях, метод Grabcut. Разница в скорости между Java и NDK составляла максимум 10%, что можно списать на ошибку, так как мне не удалось получить в тот момент абсолютно одинаковые изображения.
Обновлять.
Довольно неприятно признавать собственные ошибки, но что поделаешь? Итак, вот пример кода, с помощью которого я оценивал производительность Java-реализации библиотеки OpenCV:
Теги: #android ndk #приложения для Android #Android #разработка Androidfor (int i=0; i<mat.rows(); i++){
-
Опыт Разборки Ноутбука Acer Aspire 5750G
19 Oct, 24 -
Сегодня Wordpress Исполняется 7 Лет
19 Oct, 24 -
Опытные Маркетологи
19 Oct, 24