Ускорение выборки `srand(time(NULL));`
есть рандом в диапазоне 0-8 (0,1,2,3,4,5,6,7,8)
на вход приходит условие что результат может быть только 1 и 2 или 5 и7 или все кроме 2 или вообще любое сочетание( не все 9 значений или все, главное не одно )
вопрос в том чтобы быстро рандом срабатывал (например! когда нужно вернуть 2 или 5 очень долго перебирает чтобы вернуть либо 5 либо 2)
m02: int rnd; srand(time(NULL)); rnd = rand() % 9;
if ((rnd == 0) || (rnd == 2) || (rnd == 6) || (rnd == 8))
{return rnd;} else { goto m02; }
как заставить функцию работать быстрее, как в плюсах грамотно сделать. спасибо.
Ответы (2 шт):
В вашем коде есть неприятное место:
srand(time(NULL));
rnd = rand() % 9;
Этот код в течении одной секунды выдаёт одно и то же значение. time(NULL) выдаёт текущее время с разрешением в одну секунду. srand сбрасывает случайный генератор, затем вы спрашиваете первое случайное число. Если оно вас устраивает, то в течении секунды вы будете его выдавать снова и снова. Если число вас не устраивает, цикл будет ждать конца секунды. После чего процесс повторится.
Вам нужна функция в которую вы передадите массив цифр (вариантов для выбора). Функция выберет один из элементов случайным образом и вернёт. Все достаточно быстро, числа будут настолько случайные насколько это возможно.
#include <random>
#include <iostream>
#include <vector>
class Sampler {
public:
int get_random(const std::vector<int> &values) {
std::uniform_int_distribution<> distrib(0, values.size() - 1);
return values[distrib(gen)];
}
private:
std::mt19937 gen;
};
int main() {
const std::vector<int> digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
Sampler s;
for (int i = 0; i < 10000000; ++i) {
std::cout << s.get_random(digits) << '\n';
}
}
Десять миллионов случайных цифр в секунду:
$ g++ -std=c++17 -pedantic -Wall -Wextra -Werror -O3 slow-random.cpp $ time ./a.out | wc -l 10000000 real 0m0.857s user 0m0.872s sys 0m0.024s
Вы хотите в самом деле быстро?
Тогда упростите вывод результата, насколько возможно (переход от printf() к putchar() дает выигрыш в 5 раз)
(ну, и берите несколько маленьких чисел из одного вызова random() (улучшает время вдвое))
#include <stdio.h>
#include <stdlib.h>
int
main (int ac, char *av[])
{
int d[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
/* 1.
for (int i = 0; i < 10000000; i++)
printf("%d\n", d[random() % 9]);
avp@avp-desktop:~/avp/hashcode$ gcc ttt.c -O3
avp@avp-desktop:~/avp/hashcode$ time ./a.out | wc -l
10000000
real 0m0.568s
user 0m0.582s
sys 0m0.025s
*/
/* 2.
for (int i = 0; i < 10000000; i++)
putchar(d[random() % 9]+'0'), putchar('\n');
avp@avp-desktop:~/avp/hashcode$ gcc ttt.c -O3
avp@avp-desktop:~/avp/hashcode$ time ./a.out | wc -l
10000000
real 0m0.103s
user 0m0.132s
sys 0m0.013s
*/
// А вот это в самом деле быстро
for (int i = 0; i < 10000000 / 5; i++) {
int r = random();
for (int j = 0; j < 5; j++, r >> 5)
putchar(d[(r & 0x1f) % 9] + '0'), putchar('\n');
}
/*
avp@avp-desktop:~/avp/hashcode$ gcc ttt.c -O3
avp@avp-desktop:~/avp/hashcode$ time ./a.out | wc -l
10000000
real 0m0.064s
user 0m0.056s
sys 0m0.049s
*/
return 0;
}