[devel] конкатенация строк
Alexander Bokovoy
=?iso-8859-1?q?ab_=CE=C1_altlinux=2Eorg?=
Ср Ноя 28 21:56:14 MSK 2007
Alexey Tourbin пишет:
> В общем, когда вопрос "эффективности" кода актуален, что случается
> редко, то, оказывается, проверки размеров буфера проще делать вручную
> и дальше использовать "старые добрые" strcpy и strcat.
>
> В общем-то я никому не советую использовать этот мой подход, unless,
> как говорится, you really-really know what you're doing.
>
> Общая проблема тут скорее в том что на Си всего этого лучше не делать
> вообще.
Нужно написать один раз грамотно и использовать в виде библиотеки.
Есть два распространенных подхода: придумывать новый вариант или носить
исправления существующих интерфейсов, которые в некоторых системах
"сломаны". Пример первого подхода -- talloc(3) в Samba, второго --
разнообразные libroken (в Heimdal) и libreplace (в Samba4).
talloc(3) (http://talloc.samba.org/) реализует механизм работы с памятью
при помощи ведения иерархии распределенных фрагментов. Идея состоит в
том, что при работе с различными структурами данных у нас довольно часто
выделение памяти происходит в зависимости от других, ранее
распределенных структур. Фактически, в результате такого распределения у
нас образуется дерево фрагментов, связанных между собой логическими
зависимостями. talloc(3) опирается на эти зависимости и предлагает
сделать их более контроллируемыми: если структура {b} появляется в
результате создания структуры {a} и по идее должна существовать не
дольше срока жизни {a}, то почему бы их не связать друг с другом?
talloc(3) определяет, что каждый указатель на память, распределенную
средствами библиотеки, может служить "родителем" для любого другого
указателя. При уничтожении {a} произойдет автоматическое уничтожение
{b}. Если {b} представляет из себя нетерминальный тип -- структуру,
которая содержит ссылки на другие, независящие от иерархии
распределения, объекты (файловые дескрипторы или еще что), то можно
определить дополнительно деструктор, который будет вызван при
уничтожении {b}.
Такой подход дает возможность очень гибкой и ошибкоустойчивой работы со
строками, а также постоянный контроль типов и защиту от несовпадения
типов при работе со структурными элементами.
Обратной стороной является некоторое падение производительности: до 3%
процентов в общем случае при использовании glibc's malloc() в качестве
"драйвера" для talloc(3). Для специфических ситуаций вроде распределения
большого количества малых фрагментов памяти -- коротких строк,
конкатенации большого количества малых фрагментов и тому подобное, можно
выбрать другие распределители. Например, можно использовать
распределитель, основанный на анонимной mmap-памяти, написанный Andrew
Tridgell-ом: http://samba.org/~tridge/junkcode/alloc_mmap/. Этот
распределитель снижает расход памяти в Samba4 приблизительно на 10-15%
на соединение и работает быстрее. Или можно использовать tcmalloc
(http://goog-perftools.sourceforge.net/doc/tcmalloc.html) или emeamoa
(http://code.google.com/p/ememoa/)
Но это снизу, а уровнем выше talloc(3) дает хороший уровень абстракции и
удобства работы со строками и структурами, включая отладку -- любая
такая иерархия может автоматически распечатать свою структуру.
--
/ Alexander Bokovoy
Samba Team http://www.samba.org/
ALT Linux Team http://www.altlinux.org/
Midgard Project Ry http://www.midgard-project.org/
Подробная информация о списке рассылки Devel