std::map выделения памяти
От: maks1180  
Дата: 30.11.22 01:18
Оценка:
Как я понял по умолчанию std::map выделяет новый блок памяти в куче для каждой пары ключ-значение.
И освобождает его через free() когда мы удаляем пару через map.erase(map.find(key)).

Для ускорения работы, хотел бы поменять его поведение:
например сразу выделять место по 1000 пар ключ-значение, при удалении не вызывать free для каждой пары.

Как это можно сделать ?
===============================================
(реклама, удалена модератором)
Отредактировано 30.11.2022 1:18 maks1180 . Предыдущая версия .
Re: std::map выделения памяти
От: Stanislav V. Zudin Россия  
Дата: 30.11.22 05:50
Оценка: 1 (1) +3
Здравствуйте, maks1180, Вы писали:

M>Как я понял по умолчанию std::map выделяет новый блок памяти в куче для каждой пары ключ-значение.

M>И освобождает его через free() когда мы удаляем пару через map.erase(map.find(key)).

M>Для ускорения работы, хотел бы поменять его поведение:

M>например сразу выделять место по 1000 пар ключ-значение, при удалении не вызывать free для каждой пары.
M>Как это можно сделать ?

Это очевидно. Своим аллокатором.
template<

    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T>>
> class map;


Вот только зачем?
Что за задачу решаешь?
Пляски с аллокаторами — оптимизация на спичках очень редкая задача.

Если это для расширения кругозора, то ИМХО лучше потратить время на изучение структур данных и алгоритмов — пользы больше.
_____________________
С уважением,
Stanislav V. Zudin
Re: std::map выделения памяти
От: watchmaker  
Дата: 30.11.22 06:38
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Как я понял по умолчанию std::map выделяет новый блок памяти в куче для каждой пары ключ-значение.

M>Для ускорения работы, хотел бы поменять его поведение:
M>например сразу выделять место по 1000 пар ключ-значение, при удалении не вызывать free для каждой пары.

У std::map есть node interface ровно для этого. Смотри перегрузки методов, принимающие или возвращающие тип std::map<>::node_type.


M>И освобождает его через free() когда мы удаляем пару через map.erase(map.find(key)).

Ну всё же не совсем через free.
Re: std::map выделения памяти
От: sergii.p  
Дата: 30.11.22 08:53
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Для ускорения работы, хотел бы поменять его поведение:

M>например сразу выделять место по 1000 пар ключ-значение, при удалении не вызывать free для каждой пары.

boost::flat_map
Re[2]: std::map выделения памяти
От: flаt  
Дата: 30.11.22 08:55
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:


SVZ>Вот только зачем?

SVZ>Что за задачу решаешь?

http://rsdn.org/forum/cpp/8418454
Автор: maks1180
Дата: 30.11.22
Re[3]: std::map выделения памяти
От: Stanislav V. Zudin Россия  
Дата: 30.11.22 09:06
Оценка: +2
Здравствуйте, flаt, Вы писали:

SVZ>>Вот только зачем?

SVZ>>Что за задачу решаешь?

F>http://rsdn.org/forum/cpp/8418454
Автор: maks1180
Дата: 30.11.22


??? И?

Сколько элементов в этом мапе? Какого размера?
Существующий код тормозит?
Профилятор это подтверждает?
Другими структурами данных этот мап не заменить?
Какую скорость надо достичь?

Пока, судя по другим вопросам ТС, у меня складывается впечатление, что интерес исключительно академический.
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: std::map выделения памяти
От: flаt  
Дата: 30.11.22 09:19
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:


SVZ>Пока, судя по другим вопросам ТС, у меня складывается впечатление, что интерес исключительно академический.


Именно. Просто пишет свой фреймворк, все такими были.
Re[4]: std::map выделения памяти
От: rg45 СССР  
Дата: 30.11.22 12:01
Оценка: +2
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Пока, судя по другим вопросам ТС, у меня складывается впечатление, что интерес исключительно академический.


У меня впечатление такое, что человек занимается преждевременной оптимизацией, отодвинув на задний план остальные вопросы — надежность, поддерживаемость, масштабируемость и пр.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: std::map выделения памяти
От: rudzuk  
Дата: 30.11.22 12:33
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:

r> У меня впечатление такое, что человек занимается преждевременной оптимизацией, отодвинув на задний план остальные вопросы — надежность, поддерживаемость, масштабируемость и пр.


ТС — автор Ammyy Admin, поэтому, думается, занимается он не преждевременной оптимизаций.
avalon/3.0.1
Re[5]: std::map выделения памяти
От: maks1180  
Дата: 01.12.22 04:07
Оценка:
SVZ>>Пока, судя по другим вопросам ТС, у меня складывается впечатление, что интерес исключительно академический.

R>У меня впечатление такое, что человек занимается преждевременной оптимизацией, отодвинув на задний план остальные вопросы — надежность, поддерживаемость, масштабируемость и пр.


Да, это так — преждевременная оптимизация, переписываю софт, а раз уж начал переписывать, то хочу сразу сделать хорошо, что-бы потом не переделывать.
У софта сейчас нагрузка по 150 тыс соединений, ранее я тестировал и на 300 тыс выдерживал, вот хочу переписать и потом потестировать на 1 млн соединений.

Я понимаю, что моя текуща задача решается увеличением количества серверов, и решается наверно дешевле, чем мои труды.
Но мне для себя хочется сделать, что-бы потом с гордостью сказать, что я написал софт который выдерживает Х нагрузку, и поэтому смогли сократить количество серверов в Y раз.
===============================================
(реклама, удалена модератором)
Re[2]: std::map выделения памяти
От: maks1180  
Дата: 01.12.22 04:10
Оценка:
M>>Для ускорения работы, хотел бы поменять его поведение:
M>>например сразу выделять место по 1000 пар ключ-значение, при удалении не вызывать free для каждой пары.
M>>Как это можно сделать ?

SVZ>Это очевидно. Своим аллокатором.


Это понятно, просто думал может есть другие варианты или что-то по существу подскажите.

Свой аллокатор будет всегда через ассемблерный call вызываться или может быть заинлайнин ?

SVZ>Если это для расширения кругозора, то ИМХО лучше потратить время на изучение структур данных и алгоритмов — пользы больше.

Это я уже и так неплохо знаю.
===============================================
(реклама, удалена модератором)
std::map итератор
От: maks1180  
Дата: 01.12.22 08:46
Оценка:
Я правильно понимаю, что итератор у map это фактически адрес map::node и поэтому я могу добавлять и удалять другие элементы и итератор останется валидным.
Или это зависит от реализации ?
===============================================
(реклама, удалена модератором)
Отредактировано 01.12.2022 8:47 maks1180 . Предыдущая версия .
Re[3]: std::map выделения памяти
От: Stanislav V. Zudin Россия  
Дата: 01.12.22 09:06
Оценка:
Здравствуйте, maks1180, Вы писали:

SVZ>>Это очевидно. Своим аллокатором.

M>Это понятно, просто думал может есть другие варианты или что-то по существу подскажите.
M>Свой аллокатор будет всегда через ассемблерный call вызываться или может быть заинлайнин ?

Т.к. там шаблонная магия, то может быть и заинлайнен.

SVZ>>Если это для расширения кругозора, то ИМХО лучше потратить время на изучение структур данных и алгоритмов — пользы больше.

M>Это я уже и так неплохо знаю.

Просто мне кажется, ты не с той стороны пытаешься оптимиздить.
Но т.к. данных для обсуждения нет, а телепаты, как всегда, в отпуске , то и советы общие.

Замена мапа на хеш может дать прирост скорости.
Замена хеша на плоский хеш (на базе массива) может дать прирост. А может и не дать

Отказаться от удаления вообще, "удаленные" элементы переиспользовать.

Ну и т.д., я бы начал с алгоритмической оптимизации. Возможно, тюнить хип и аллокаторы и вовсе не потребуется.
_____________________
С уважением,
Stanislav V. Zudin
Re: std::map итератор
От: Stanislav V. Zudin Россия  
Дата: 01.12.22 09:09
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Я правильно понимаю, что итератор у map это фактически адрес map::node


Типа того.

M>поэтому я могу добавлять и удалять другие элементы и итератор останется валидным.


Можешь, Стандарт гарантирует.
_____________________
С уважением,
Stanislav V. Zudin
Re: std::map итератор
От: sergii.p  
Дата: 01.12.22 09:09
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Я правильно понимаю, что итератор у map это фактически адрес map::node и поэтому я могу добавлять и удалять другие элементы и итератор останется валидным.

M>Или это зависит от реализации ?

да, https://en.cppreference.com/w/cpp/container/map/insert

No iterators or references are invalidated

Re[6]: std::map выделения памяти
От: rg45 СССР  
Дата: 01.12.22 09:49
Оценка: +2
Здравствуйте, maks1180, Вы писали:

M>Да, это так — преждевременная оптимизация, переписываю софт, а раз уж начал переписывать, то хочу сразу сделать хорошо, что-бы потом не переделывать.

M>У софта сейчас нагрузка по 150 тыс соединений, ранее я тестировал и на 300 тыс выдерживал, вот хочу переписать и потом потестировать на 1 млн соединений.

Такая вот оптимизация "на всякий случай" всего подряд может привести к обратным результатам — и оптимизации толком не получится, потому что неправильно были выявлены узкие места, и дизайн с архитектурой получатся такими, что в скором времени появится кто-то, кто в очередной раз захочет "переписать все нахрен". И этот порочный круг может повторяться бесконечно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 01.12.2022 9:52 rg45 . Предыдущая версия . Еще …
Отредактировано 01.12.2022 9:52 rg45 . Предыдущая версия .
Re: std::map выделения памяти
От: _NN_ www.nemerleweb.com
Дата: 01.12.22 10:38
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Как это можно сделать ?


Уже ответили про аллокатор.
Могу дополнить, что прежде всего главный вопрос про выбранную структуру данных.
Нужен ли упорядоченный контейнер, может unordered_map будет более подходящим, а также более и быстрым.

Также начиная с C++17 ассоциативные контейнеры получили дополнительные методы как insert, extract, которые позволяют избежать лишних копирований и выделений памяти.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: std::map выделения памяти
От: maks1180  
Дата: 02.12.22 04:52
Оценка:
SVZ>Замена мапа на хеш может дать прирост скорости.
SVZ>Замена хеша на плоский хеш (на базе массива) может дать прирост. А может и не дать

Ну у меня как раз через свой хэш написано, разбивается на 1024 корзины и при 300.000 объектов примено 300 шт в корзине.
Но далее по корзине идёт перебор (т.к. там не отсортированы они).
Если ли более интересные реализации хэша ?
===============================================
(реклама, удалена модератором)
Re[5]: std::map выделения памяти
От: Stanislav V. Zudin Россия  
Дата: 02.12.22 07:23
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Ну у меня как раз через свой хэш написано, разбивается на 1024 корзины и при 300.000 объектов примено 300 шт в корзине.

M>Но далее по корзине идёт перебор (т.к. там не отсортированы они).
M>Если ли более интересные реализации хэша ?

Мы делали свой плоский хеш из трёх массивов

std::vector<KEY> Items;    // Ключи
std::vector<int> Next;     // Список коллизий (односвязный список)

std::vector<int> First;    // Голова списка коллизий


Items.size() == Next.size();
это очевидно

Массив First по своей сути это твои корзины.
First.size() >= Items.size()

При добавлении очередного элемента в хеш, если количество элементов превысило число корзин, списки коллизий перестраиваются.
Хеш функция вычисляет положение элемента в массиве First. Но это стандартно.

Про выбор числа корзин.
1024 — очень плохое число. Оно красивое, но даёт много коллизий.
Простые числа используют неспроста.
У нас использовался какой-то коэффициент, чтобы после ресайза размер First не был кратным степени двойки.
В принципе можно брать ряд простых чисел — очень популярное решение. Но на больших размерах этот массив будет расти слишком уж сильно.
Поэтому нужен компромисс.

При таком подходе списки коллизий не вырастали больше 2-3 штук.
Удаление мы не делали. Пришлось бы перестраивать хеш, т.к. индексы поедут, а это дорого. Проще пометить элемент вакантным и при совпадении хеша занять готовое место.

Если известно, сколько примерно будет элементов в хеше, можно заранее выделить память под массив First. Позволит избежать лишних пересчетов хешей.

Ну вот так как-то.
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: std::map выделения памяти
От: PM  
Дата: 04.12.22 09:05
Оценка: 18 (3)
Здравствуйте, maks1180, Вы писали:

M>Ну у меня как раз через свой хэш написано, разбивается на 1024 корзины и при 300.000 объектов примено 300 шт в корзине.

M>Но далее по корзине идёт перебор (т.к. там не отсортированы они).
M>Если ли более интересные реализации хэша ?

Звучит как одна из наивных реализаций.
Рекомендую глянуть на свежие результаты сравнения разных хэш-таблиц, на разработку которых тратится много времени и денег:
https://martin.ankerl.com/2022/08/27/hashmap-bench-01/

Похоже хэш-таблицы с открытой адресацией выглядят предпочтительнее на современных архитектурах с их многоуровневыми кэшами.
Интересная статья про одну из таких: https://bannalia.blogspot.com/2022/11/inside-boostunorderedflatmap.html
Отредактировано 04.12.2022 9:40 PM . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.