Производительность, как к ней ни подходить, воспринимается субъективно. Если пользователю кажется, что производительность приложения низкая, оно обладает слабой интерактивностью или им неудобно пользоваться, то из такой его оценки и надо исходить. Уделяйте пристальное внимание тем деталям, от которых зависит, какой будет субъективная оценка, данная вашему приложению пользователями, — хорошей или плохой. По этой причине весьма полезно создавать прототипы идей и привлекать для их тестирования пользователей реальных устройств. Те, кто пользуется мобильными устройствами, желают получать от них осязаемые подтверждения того факта, что интерактивная связь между пользователем и устройством ни на минуту не разрывается. Не чувствуя ответной реакции устройства после отправки ему запроса, пользователи очень скоро начинают беспокоиться. Всегда старайтесь, чтобы в процессе работы вашего приложения беспокойство пользователя по этому поводу было сведено к минимуму. Не заставляйте пользователей гадать — происходит что-то или не происходит; незамедлительно давайте им знать о том, что устройство занято обслуживанием их запроса.
Наконец, подходите ко всему творчески. Напряженная работа и творческий подход позволяют решить практически любую проблему. Если вы приходите к выводу, что дальнейшее повышение производительности связано с фундаментальными ограничениями ваших алгоритмов, то не исключено, что настал момент повторно рассмотреть основные цели приложения и постараться изыскать новые способы их достижения. Великие идеи рождаются в процессе решения проблем, которые сразу кажутся неприступными. Творческое рассмотрение проблем производительности будет для вас не только увлекательным занятием, но и сторицей себя окупит.
ГЛАВА 8
Производительность и управление памятью
"Человеческая голова подобна комнате, в которой необходимо держать только те вещи, которые вам непосредственно нужны, а все остальные — убирать подальше в чулан, откуда их можно будет в любой момент достать, когда они понадобятся."
Артур Конан-Дойль (Encarta 2004, Quotations)
Определение модели памяти для приложения
Согласно приведенному выше суждению автора рассказов о Шерлоке Холмсе, необходимо различать ресурсы, которые должны быть всегда под рукой, и ресурсы, которые лучше всего переместить в долговременное хранилище. Применительно к мобильным устройствам это означает, что вы должны хорошенько подумать над тем, какую модель памяти следует использовать.
Самое важное, что можно сказать о модели памяти, — это то, что она должна у вас быть. Было бы слишком легкомысленно допустить, чтобы в процессе разработки приложения разрастались сами по себе неконтролируемым образом, а не в соответствии с предварительно составленным планом. В случае приложений для настольных компьютеров это часто приводит к малопонятному коду, который трудно сопровождать и обновлять, и приложениям, которые функционируют не столь надежно и эффективно, как следовало бы. В случае мобильных приложений использование "сырой" модели памяти приводит к приложениям, которые обязательно упираются в "стену производительности", в результате чего они никогда не смогут функционировать так, как надо. В подобных ситуациях обычно трудно устранить проблемы, не прибегая к широкомасштабной переделке проекта. Разработка хорошо продуманной модели памяти позволяет избежать этой трясины и сделать проект более гибким. Целесообразно рассматривать использование памяти приложения на двух различных уровнях:
1. Управление памятью на макроскопическом "уровне приложения". Этот уровень относится к данным и ресурсам уровня приложения, которые поддерживаются вашим приложением в процессе выполнения. Эти данные обычно существуют в течение длительного времени, и их область видимости не ограничивается пределами отдельных функций. Для создания эффективно функционирующего мобильного приложения очень важно иметь надежную модель, управляющую объемом данных, подлежащих хранению в памяти в каждый момент времени, и удалением из памяти данных и ресурсов, непосредственное использование которых в ближайшее время не ожидается. Чрезмерный объем долгоживущих данных состояния загромождает память, которую можно было бы использовать для кэширования JIT-компилированного кода или как рабочую память для функций, и заставляет многократно и не самым эффективным образом очищать память от "мусора".