Сравнение библиотеки Binary Preferences со стандартными Shared Preferences

В системе Android для хранения какой-либо информации используются пары “ключ-значение”. С их помощью можно хранить значения переменных, либо различные сведения, которые в будущем могут понадобиться приложению.

И хотя в SDK уже есть готовый интерфейс, называемый SharedPreferences, который предоставляет методы для сохранения и чтения настроек в приложении, существуют различные библиотеки, реализующие задачу иными способами. Одной из таких библиотек является Binary Preferences.

Данная библиотека является быстрой и лёгкой заменой  SharedPreferences. Её особенностью является то, что она работает с дисками через асинхронный NIO (Non-blocking I/O) и хранит каждую пару “ключ-значение” в отдельном файле. Кроме того, библиотека обладает следующими преимуществами:

  • Лёгкая, без лишних зависимостей;
  • Быстрее, чем SharedPreferences;
  • Малый объём занимаемой памяти при сериализации\десериализации данных;
  • Нет копирования области памяти;
  • Содержит только двоичные данные, не XML или JSON;
  • Поддерживает шифрование данных;
  • Полная обратная совместимость с интерфейсом SharedPreferences;
  • Хранит любые примитивы;
  • Полностью оптимизированная поддержка межпроцессного взаимодействия (IPC);
  • Обработка различных исключений.

Более подробно об этой библиотеке можно прочитать на странице репозитория.

Сравним работу SharedPreferences и Binary Preferences, для этого напишем приложение, выполняющие одинаковые операции сначала стандартными средствами, а затем с помощью библиотеки.

Для этого создадим объект SharedPreferences и добавим в него переменные разных типов и сохраним.

SharedPreferences prefs = getSharedPreferences("shared_preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("test_string", "Тестовое сообщение");
editor.putBoolean("test_boolean", true);
editor.putInt("test_int", 2536);
editor.putFloat("test_float", (float) 1000.53);
editor.apply();

Запустим приложение и запишем данные.

Теперь посмотрим, сколько места заняли данные на устройстве, для этого понадобится root-доступ, чтобы попасть в папку /data/data/androidtools.pef_test, которая находится в корне системы. Подробнее о том, как получить root, можно прочитать здесь.

Внутри этой папки находится папка shared_prefs, где и хранятся наши данные. Данные хранятся в XML-файле, имя которого идентично первому параметру getSharedPreferences() (в данном случае – shared_preferences.xml).

Как видно из скриншота, данные занимают 284 байта в памяти.

Сравним теперь с работой Binary Preferences. Поскольку интерфейс является наследником SharedPreferences и SharedPreferences.Editor, различия в коде будут минимальны.

Главный упор в библиотеке, сделан на хранение сложных объектов, состоящих из множества полей через интерфейс Persistable.

Таким образом, достигаются малые накладные расходы на сериализацю/десериализацию данных, т.е. нету перегона в xml и json, что может быть критично в некоторых проектах.

Preferences prefs = new BinaryPreferencesBuilder(getApplicationContext()).build();
PreferencesEditor editor = prefs.edit();
editor.putString("test_string", "Тестовое сообщение");
editor.putBoolean("test_boolean", true);
editor.putInt("test_int", 2536);
editor.putFloat("test_float", (float) 1000.53);
editor.apply();

Аналогично запустим приложение и запишем данные.

Посмотрим на файлы, только на этот раз нам нужна папка не shared_prefs, а files. Значения внутри неё хранятся в preferenсes/имя_предпочтения/values.

Как и говорилось в особенностях библиотеки, каждая пара “ключ-значение” находится в отдельном файле, и в сумме они занимают всего 48 байт.

Отсюда можно сделать вывод, что чем больше данных нужно будет хранить приложению, тем больше будет выигрыш по памяти устройства.

Кроме того, можно замерить размеры APK обеих версий, для этого нам необходима утилита APK Analyzer, интегрированная в Android Studio. Сравнение получившихся APK можно увидеть в таблице ниже.

Shared Preferences Binary Preferences
Размер в несжатом виде 803,7 КБ 894,9 КБ
Размер в сжатом виде 613 КБ 626 КБ
Сколько содержит классов 684 755
Сколько содержит методов 5611 5944

Количество методов в самой Binary Preferences узнать можно тут http://www.methodscount.com/?lib=com.github.iamironz%3Abinaryprefs%3A0.9.9.9

Стандартные методы Android SDK не всегда могут эффективно выполнять свои задачи, и тут на помощь приходят пользовательские библиотеки, которые вполне могут работать быстрее и эффективнее, улучшая работоспособность приложения в целом.

Сравнение библиотеки Binary Preferences со стандартными Shared Preferences: 5 комментариев

  1. Revertron

    Проблема в том, что если файл и занимает вроде бы 2 байта, то он всё равно занимает 2-4 килобайта на флэшке, в зависимости от файловой системы. То есть, накладных расходов будет НАМНОГО БОЛЬШЕ.

      1. Андрей

        Это не “умозаключения”, как вы предполагаете, а твёрдое знание об устройстве файловых систем на блочных устройствах.
        Они потому и называются “блочными”, что работают не с отдельными байтами, а с большими блоками – начиналось всё с 512-байтных блоков, современные HDD имеют уже 4096-байтные блоки.
        С flash-устройствами, используемыми в гаджетах, всё ещё хуже – несмотря на то, что они эмулируют 512-байтный блочный интерфейс, физически флеш-память перезаписывается 128К-байтными строками. Отсюда – “проблема TRIM”, когда для поддержания высокой скорости записи на флешку нужно физически очищать ячейки её памяти.
        Файловая же система работает с блоками более крупного размера – 8192 байт, как правило. Поэтому, что вы запишете 48 байт в файл на диске, что запишете 284 байта – всё едино: свободное место на диске уменьшится на 8К.
        Почитайте, пожалуйста, Википедию – там достаточно хорошо и подробно всё это расписано. Но – многословно, да.

        Другими словами – автор статьи решает надуманную, несуществующую проблему. Хотя, не спорю, решать её и интересно и увлекательно…

        1. iamironz

          Ну слишком толсто, Андрей. Позволь напомнить что дело не в этом, а в том что накладные расходы на парсинг и disk io у тебя будут меньше, если ты пишешь блоб а не километровый xml. Автор статьи не раскрыл суть и необходимость. Да и в общем-то не очень надо, никого не принуждаю.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *