понедельник, 12 января 2009 г.

Boost.Flyweight

Вчера наткнулся на новую библиотеку, которая будет в новой (1.38) версии Boost. Сейчас ее тестируют и судя по всему все работает неплохо. Ее название Boost.Flyweight (link пока работает, потом документация будет перенесена).

Общая идея проста - создать некий репозиторий, который хранит только уникальные объекты. Вообщем шаблон проектирования так и называется Flyweight, что по русски звучит как "Приспособленец". К примеру, если у вас есть объект буква и вы хотите хранить для нее информацию о шрифте, размере, стилях и т.д, то в итоге даже небольшой текст состоящий из таких букв будет отнимать у системы довольно много ресурсов. Хотя при анализе мы увидим, что в этой информации очень много повторяющихся блоков, которые хорошо было бы организовать таким образом, что хранится только один, а сами буквы имеют только ссылки на этот уникальный блок. Такой механизм наиболее прозрачным образом и реализует Flyweight. 

Здесь стоит так же упомянуть, что в Flyweight блоки нельзя менять напрямую, так как много объектов могут делить одну информацию, то смена данных блока повлечет смену данных во всех объектах. Авторы правда говорят, что если сменить данные то или ссылка прыгнет на другой блок, где есть такие же данные, или система создаст новый блок. 

Как это работает все? К примеру у вас есть объект и вам требуется хранить в системе огромное количество его экземпляров:

struct user_entry
{
std::string first_name;
std::string last_name;
int age;
...
};

Очевидно, что имена будут часто повторяться и это требуемое количество памяти можно уменьшить используя Flyweight:

#include <boost/flyweight.hpp>
struct user_entry
{
flyweight <std::string> first_name;
flyweight <std::string> last_name;
int age;
...
};

Эти переменные работают как и обычные переменные, потому и пересывать остальной код нет необходимости (в этом я вижу огромное удобство) - конструкторы, операторы отношения, сериализация... Теперь в системе будет создан некий словарь строк и если будет создан объект с именами, которые уже попадались в системе, то новая память выделена не будет, а будут использованы лишь ссылки.

Осталось только подождать релиза и попробовать на деле.

2 комментария:

  1. идея напоминает символы в ruby

    ОтветитьУдалить
  2. да очень похоже, хотя и имеет немного другое назначение - в больших хранилищах может быть полезным

    ОтветитьУдалить