Где лучше хранить random_device/mt19937?

У меня есть функция, которая использует случайность

void fun() {
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<double> dis(0.0, 1.0);
    // ...
}

И, как я подозреваю, я получу плохой рандом, если он будет вызываться повторно, и каждый раз будут создаваться и rd, и gen. Не лучше ли сделать эти переменные глобальными/приватными полями класса, чтобы они не переопределялись несколько раз?

Эм, почему бы тебе просто не сделать это?

Nicol Bolas 16.02.2023 06:19

Вам нужно только сохранить mt19937, так как вы используете random_device только один раз во время инициализации.

HolyBlackCat 16.02.2023 06:25

Создайте генератор один раз в main, передайте ссылку на весь код, который в нем нуждается. (Избегает использования глобальных переменных/внедрения зависимостей). Вы, вероятно, также захотите сделать то же самое для дистрибутива, который также не должен постоянно пересоздаваться. Вы также можете поместить оба в структуру в качестве членов и передать их (как случайный контекст)

Pepijn Kramer 16.02.2023 06:49

@PepijnKramer Не могли бы вы объяснить, чем «передача ссылки на код, который в ней нуждается», отличается от внедрения зависимостей?

wtz 16.02.2023 07:50

@wtz это инъекция зависимостей :) Теперь я вижу, что мой текст немного не тот :/

Pepijn Kramer 16.02.2023 07:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать random_device для создания начального числа для инициализации mt19937. Поскольку random_device — затратная операция, ее не нужно вызывать каждый раз при вызове функции, и нет необходимости сохранять random_device.

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

void func() {
  thread_local mt19937(random_device{}());
}
Ответ принят как подходящий

Генератор случайных чисел должен быть глобальным объектом. Но нет ничего плохого в том, чтобы похоронить его в функции доступа:

template <typename RealType>
RealType random_real_in_range( RealType min = 0., RealType max = 1. )
{
  thread_local std::mt19937 rng( std::random_device{}() );
  return std::uniform_real_distribution<RealType>( min, max )( rng );
}

Недостаток здесь в том, что МТ действительно нужно «разогреть» звонком .discard( 1000 ) или около того...

Другие вопросы по теме

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

Есть ли существенная разница между использованием встроенного генератора случайных чисел и использованием криптографического генератора случайных чисел?
Вставить по порядку ряд битов в байт (u_int8_t)
С++: нужен ли виртуальный деструктор для объектов, выделенных в стеке?
Имеет ли GCC11 регрессию, в которой он неправильно принимает указатель на массив абстрактного класса
Явное создание объектов с помощью тривиального конструктора по умолчанию с использованием нового размещения в C++17
Каков наиболее ресурсоэффективный способ проверить, содержат ли два списка std::list одинаковые уникальные элементы?
С++: получение случайных символов в качестве вывода, не знаю, почему
Unordered_map из собственного типа путем перегрузки оператора() не работает
Измерение вертикального расстояния бинаризованного изображения (Open CV) C++
Можно ли автоматически сопоставлять и перенаправлять типы в контексте структуры на параметры функции с помощью шаблонов C++?