Tôi đã thực hiện một lớp được gọi QuickRandom
và công việc của nó là tạo ra các số ngẫu nhiên một cách nhanh chóng. Điều đó thực sự đơn giản: chỉ cần lấy giá trị cũ, nhân với a double
và lấy phần thập phân.
Đây là QuickRandom
toàn bộ lớp học của tôi :
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;
}
}
Và đây là đoạn mã tôi đã viết để kiểm tra nó:
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);
}
Đó là một thuật toán rất đơn giản, chỉ cần nhân đôi số trước với số nhân "số ma thuật". Tôi đã ném nó cùng nhau khá nhanh, vì vậy tôi có thể làm cho nó tốt hơn, nhưng kỳ lạ thay, nó dường như đang hoạt động tốt.
Đây là đầu ra mẫu của các dòng nhận xét trong main
phương thức:
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
Hừm. Khá ngẫu nhiên. Trong thực tế, điều đó sẽ làm việc cho một trình tạo số ngẫu nhiên trong một trò chơi.
Đây là đầu ra mẫu của phần không bình luận:
5456313909
1427223941
Ồ Nó thực hiện nhanh hơn gần 4 lần Math.random
.
Tôi nhớ đã đọc ở đâu đó Math.random
sử dụng System.nanoTime()
và hàng tấn mô-đun điên và công cụ phân chia. Điều đó có thực sự cần thiết? Thuật toán của tôi thực hiện nhanh hơn rất nhiều và có vẻ khá ngẫu nhiên.
Tôi có hai câu hỏi:
- Thuật toán của tôi có "đủ tốt" không (ví dụ, một trò chơi, trong đó các số thực sự ngẫu nhiên không quá quan trọng)?
- Tại sao
Math.random
làm nhiều như vậy khi nó dường như chỉ là phép nhân đơn giản và cắt bỏ số thập phân sẽ đủ?
new QuickRandom(0,5)
hoặc new QuickRandom(.5, 2)
. Cả hai sẽ liên tục xuất 0 cho số của bạn.