Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Сентябрь 12, 2011, 12:13



Название: Простой аллокатор
Отправлено: Igors от Сентябрь 12, 2011, 12:13
Добрый день

Пример - скопировать массив/контейнер без дубликатов но так чтобы порядок оставшихся сохранился. Напрашивается так

Код
C++ (Qt)
template <class TVec, class TElem>
void CopyWithoutDup( const TVec & src, TVec & dst )
{
dst.clear();
std::set <TElem> theSet;
for (size_t i = 0; i < src.size(); ++i) {
 const TElem & elem = src[i];
 if (theSet.find(elem) != theSet.end()) continue;
 theSet.insert(elem);
 dst.push_back(elem);
}
}
 
Все вполне хорошо, ну может сделать set указателей и использовать lower_bound - но не суть. Но есть одна небольшая неприятность - это притормаживает т.к. каждый insert вызывает malloc. Понятно что "официальная доктрина" - делайте custom allocator, но это не вызывает энтузиазма. Только что все было легко и просто, а тут разбирайся с классом и все такое.

Часто вполне устраивает простейший аллокатор который распределил бы память один раз на максимально возможное число элементов в set (или др. ассоциативном контейнере), это число мне известно. Есть ли такой готовый? И, по ходу дела, как с этим в Qt контейнерах ?

Спасибо

Edit: виноват, забыл упомянуть что порядок должен быть сохранен. Исправил


Название: Re: Простой аллокатор
Отправлено: Пантер от Сентябрь 12, 2011, 12:22
А если sort и unique_copy?


Название: Re: Простой аллокатор
Отправлено: brankovic от Сентябрь 12, 2011, 13:41
Лучше всего использовать сортировку, но если не получается:

В бусте есть pool allocator, похоже на ваш случай, но сам я не пользовался.

Ещё по-быстрому можно попробовать tcmalloc, много маленьких одинаковых аллокаций сильно ускоряет (это фактически pool, не намного медленее будет).

Ещё в бусте есть intrusive set. Заполняете в вектор, потом собираете intrusive_set из них, ноды остаются в векторе, удалять можно их вместе с вектором. Но тогда структура при расширении вектора может поломаться, и в TElem придётся добавить 3 указателя для хранения структуры дерева.


Название: Re: Простой аллокатор
Отправлено: Igors от Сентябрь 12, 2011, 14:57
А если sort и unique_copy?
Просто так unique_copy скопирует дубликаты если они идут не подряд. А если сначала sort - то изменится порядок следования (забыл указать, исправляю)

Лучше всего использовать сортировку, но если не получается:
Можно и с неизменным порядком через сортировку, но получается длинновато


Название: Re: Простой аллокатор
Отправлено: Akon от Сентябрь 12, 2011, 16:21
Использовать вместо set vector, с предварительным reserve(). vector будет сортированным, поиск lower_bound


Название: Re: Простой аллокатор
Отправлено: brankovic от Сентябрь 12, 2011, 16:41
изменится порядок следования
...
Можно и с неизменным порядком через сортировку...

std::stable_sort?


Название: Re: Простой аллокатор
Отправлено: Igors от Сентябрь 12, 2011, 17:31
std::stable_sort?
Я имел ввиду руками: отсортировать сначала массив указателей и.т.д. Несложно, но длинновато. А stable_sort - не вижу как поможет, насколько помню, он сохраняет изначальный порядок лишь для одинаковых ключей.

Ладно, глянем в буст. Если помните как тот аллокатор там называется - скажите. Спасибо


Название: Re: Простой аллокатор
Отправлено: brankovic от Сентябрь 12, 2011, 20:08
http://www.boost.org/doc/libs/1_47_0/libs/pool/doc/interfaces.html (http://www.boost.org/doc/libs/1_47_0/libs/pool/doc/interfaces.html)