Востребованные примеры пользовательских средств выделения C++?

Взгляните на collections.defaultdict - это позволяет вам использовать словарь как обычно, но любая попытка получить доступ к ключу, которого нет в словаре, приводит к тому, что этот ключ создается со значением по умолчанию Вы указываете.

Вы можете сделать по умолчанию плавающее число, которое по умолчанию будет равно 0.0, потому что это то, что делает плавающее число, или вы можете создать «магическое» значение и использовать его по умолчанию:

kit = collections.defaultdict(float)

kit = collections.defaultdict(return_some_magic_value)

Если вы На самом деле мы пытаемся реализовать электронную таблицу, однако я бы посоветовал вам подумать о том, как вы будете обрабатывать циклы ячеек, ссылающихся на другие ячейки. Это не совсем тривиальная проблема, и ответ на этот вопрос расскажет, как вы храните свои клетки.

Самым основным решением было бы сохранить все неразрешенное, а затем выполнить итерацию по ячейкам, выполняя оценку «сначала в глубину»: если ячейка ссылается на другую ячейку, решите ее, а затем вернитесь. Вы помечаете решенные ячейки так же, как делали их, чтобы ваша итерация и рекурсия не сталкивались. Простым подходом может быть оценка их в отдельном словаре. Вы могли бы даже использовать defaultdict, где фабричная функция фактически выполнила рекурсивную оценку для вас!

166
задан 5 revs, 2 users 57% 31 July 2014 в 06:46
поделиться

6 ответов

Как я уже упоминал здесь , я видел пользовательский Intel TBB Распределитель STL значительно улучшает производительность многопоточного приложения, просто заменяя одно

std::vector<T>

на

std::vector<T,tbb::scalable_allocator<T> >

(это быстрый и удобный способ переключения распределителя для использования изящных кучи частных потоков TBB; см. стр. 7 в этом документ )

113
ответ дан 23 November 2019 в 21:03
поделиться

Я не написал код C ++ с пользовательским распределителем STL, но могу представить веб-сервер, написанный на C ++, который использует собственный распределитель для автоматического удаления временных данных, необходимых для ответа на HTTP запрос. Пользовательский распределитель может освободить все временные данные сразу после генерации ответа.

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

7
ответ дан 23 November 2019 в 21:03
поделиться

Может быть полезно использовать пользовательские распределители для использования пула памяти вместо кучи. Это один из многих примеров.

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

18
ответ дан 23 November 2019 в 21:03
поделиться

Я работаю с механизмом хранения MySQL, который использует c ++ для своего кода. Мы' использовать собственный распределитель для использования системы памяти MySQL, а не конкурировать с MySQL за память. Это позволяет нам убедиться, что мы используем память как пользователь, настроенный для использования MySQL, а не как «лишние».

25
ответ дан 23 November 2019 в 21:03
поделиться

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

EASTL - Стандартная библиотека шаблонов Electronic Arts

79
ответ дан 23 November 2019 в 21:03
поделиться

Я здесь использую пользовательские распределители; Вы могли бы даже сказать, что это работало вокруг другого пользовательского динамического управления памятью.

Предыстория: у нас есть перегрузки для malloc, calloc, free и различных вариантов оператора new и delete, и компоновщик счастливо заставляет STL использовать их для нас. Это позволяет нам делать такие вещи, как автоматический пул небольших объектов, обнаружение утечек, выделение заполнений, свободное заполнение, распределение заполнения с помощью часовых, выравнивание строк кэша для определенных распределений и отложенное освобождение.

Проблема в том, что мы работаем в встроенная среда - недостаточно памяти для правильного учета утечек в течение длительного периода времени. По крайней мере, не в стандартной оперативной памяти - там Это еще одна куча оперативной памяти, доступная в другом месте, с помощью пользовательских функций выделения.

Решение: написать собственный распределитель, который использует расширенную кучу, и использовать его только во внутренних компонентах архитектуры отслеживания утечек памяти ... Все остальное по умолчанию - обычные перегрузки new / delete, которые отслеживают утечки. Это позволяет избежать самого отслеживания трекера (и также предоставляет немного дополнительных функций упаковки, мы знаем размер узлов трекера).

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

и использовать его только во внутренних компонентах архитектуры отслеживания утечек памяти ... Все остальное по умолчанию - обычные перегрузки new / delete, которые отслеживают утечки. Это позволяет избежать самого отслеживания трекера (и также предоставляет немного дополнительных функций упаковки, мы знаем размер узлов трекера).

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

и использовать его только во внутренних компонентах архитектуры отслеживания утечек памяти ... Все остальное по умолчанию - обычные перегрузки new / delete, которые отслеживают утечки. Это позволяет избежать самого отслеживания трекера (и также предоставляет немного дополнительных функций упаковки, мы знаем размер узлов трекера).

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

мы знаем размер узлов трекера).

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

мы знаем размер узлов трекера).

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

5
ответ дан 23 November 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: