Лучший ключевой кандидат: std::int16_t или std::int_fast16_t?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Лучший ключевой кандидат: std::int16_t или std::int_fast16_t?

Сообщение Anonymous »

В среде, использующей типы std::int* (например, std::int16_t), а также типы std::int_fast* (например, std::int_fast16_t), могут существовать общие правила, согласно которым один может быть лучше другого. Для простоты этой статьи я буду называть типы std::int* «точными» типами, а типы std::int_fast* — «быстрыми».
В качестве примера, обычно лучше всего использовать точные типы для элементов массива, поскольку ожидается, что они будут использовать меньше байтов и, следовательно, появится больше возможностей для улучшения кэширования. Другой пример: когда элементы считываются из этого массива, их можно преобразовать в быстрый тип для выполнения арифметических действий.

Код: Выделить всё

void foo() {
std::array arr {};
//  ...
std::int_fast16_t e = arr[index];
}
Менее очевидно, какой тип больше подходит для ключевых типов std::set, std::unordered_set или связанных типов карт. Имеет ли смысл предположить, что внутреннее хранилище контейнера в целом выигрывает от компактности точных типов, таких как случай массива?
Изменить: я добавил тесты для std::set и std::unordered_set, каждый с std::uint16_t и std::uint_fast16_t. Что делает тест:
  • Создает вектор из N случайных чисел (один раз).
  • В цикле N раз: очищает тестируемый контейнер, а затем помещает определенное случайное число из вектора M раз.
N — количество повторений теста, затем общее время тестов усредняется. M – количество точек, измеряемых эталоном.

Код: Выделить всё

---------------------------------------------------
std::set       | std::uint16_t | std::uint_fast16_t
---------------+---------------+-------------------
Emplace 10     | 359.072 nsec  | 344.232 nsec
Emplace 100    |   3.455 usec  |   3.298 usec
Emplace 1000   |  34.285 usec  |  32.525 usec
Emplace 10000  | 341.679 usec  | 334.176 usec
Emplace 100000 |   3.432 msec  |   3.229 msec

-------------------------------------------------------
std::unordered_set | std::uint16_t | std::uint_fast16_t
-------------------+---------------+-------------------
Emplace 10         | 405.566 nsec  | 418.305 nsec
Emplace 100        |   3.873 usec  |   3.888 usec
Emplace 1000       |  38.617 usec  |  38.708 usec
Emplace 10000      | 386.67  usec  | 387.169 usec
Emplace 100000     |   3.888 msec  |   3.894 msec
Я не буду публиковать код теста производительности, потому что код теста моего фреймворка нетривиален, но он:
  • Выполняет работу без измерения для «разогрева»
  • Измеряет с монотонным временем
  • Объединяет тесты с asm voluty("" : "+m"(container)); чтобы попытаться избежать переупорядочение
  • Выполняет чтение данных после тестов, чтобы избежать оптимизации работы


Подробнее здесь: https://stackoverflow.com/questions/798 ... t-fast16-t
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»