Я создал класс под названием QuickRandom
, и его задача - быстро создавать случайные числа. Это очень просто: просто возьмите старое значение, умножьте на double
и возьмите десятичную часть.
Вот мой класс QuickRandom
в целом:
public class QuickRandom {
private double prevNum;
private double magicNumber;
public QuickRandom(double seed1, double seed2) {
if (seed1 >= 1 || seed1 < 0) throw new IllegalArgumentException("Seed 1 must be >= 0 and < 1, not " + seed1);
prevNum = seed1;
if (seed2 <= 1 || seed2 > 10) throw new IllegalArgumentException("Seed 2 must be > 1 and <= 10, not " + seed2);
magicNumber = seed2;
}
public QuickRandom() {
this(Math.random(), Math.random() * 10);
}
public double random() {
return prevNum = (prevNum*magicNumber)%1;
}
}
И вот код, который я написал, чтобы проверить его:
public static void main(String[] args) {
QuickRandom qr = new QuickRandom();
/*for (int i = 0; i < 20; i ++) {
System.out.println(qr.random());
}*/
//Warm up
for (int i = 0; i < 10000000; i ++) {
Math.random();
qr.random();
System.nanoTime();
}
long oldTime;
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
Math.random();
}
System.out.println(System.nanoTime() - oldTime);
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
qr.random();
}
System.out.println(System.nanoTime() - oldTime);
}
Это очень простой алгоритм, который просто умножает предыдущий двойной на "магическое число". Я быстро выбросил его, так что, возможно, я мог бы улучшить его, но, как ни странно, он работает нормально.
Это пример вывода прокомментированных строк в методе main
:
0.612201846732229
0.5823974655091941
0.31062451498865684
0.8324473610354004
0.5907187526770246
0.38650264675748947
0.5243464344127049
0.7812828761272188
0.12417247811074805
0.1322738256858378
0.20614642573072284
0.8797579436677381
0.022122999476108518
0.2017298328387873
0.8394849894162446
0.6548917685640614
0.971667953190428
0.8602096647696964
0.8438709031160894
0.694884972852229
Hm. Довольно случайный. Фактически, это будет работать для генератора случайных чисел в игре.
Вот пример вывода части без комментария:
5456313909
1427223941
Ничего себе! Он выполняет почти в 4 раза быстрее, чем Math.random
.
Я помню, где-то читал, что Math.random
использовал System.nanoTime()
и тонны сумасшедшего модуля и деления. Это действительно необходимо? Мой алгоритм работает намного быстрее и кажется довольно случайным.
У меня есть два вопроса:
- Является ли мой алгоритм "достаточно хорошим" (например, игра, где действительно случайные числа не слишком важны)?
- Почему
Math.random
делает так много, когда кажется просто достаточным умножением и вырезанием десятичного числа будет достаточно?