2 回答

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
所以這里有兩個(gè)問題。1) 正如 Carlos Heuberger 所指出的,每次循環(huán)時(shí)都需要重新初始化變量。2)正如您所指出的,將除法設(shè)置為實(shí)數(shù)除法,而不是整數(shù)的“div”運(yùn)算符需要一些注意。我對(duì)您的代碼進(jìn)行了這兩項(xiàng)更改(for 循環(huán)中的前 5 行;(1.0 * 試驗(yàn))),它似乎通過了所有測(cè)試。你很親密。
public class RandomWalkers {
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
int x = 0;
int xx = 0;
int y = 0;
int yy = 0;
int numSteps = 0;
int totalNumSteps = 0;
double randNum = 0.0;
double avgSteps = 0.0;
for (long i = 0; i < trials; i++) {
x = 0;
xx = 0;
y = 0;
yy = 0;
numSteps = 0;
while (Math.abs(x - xx) + Math.abs(y - yy) != r) {
randNum = Math.random();
if (randNum <= .25) {
// North
yy++;
} else if (randNum <= .5) {
// East
xx++;
} else if (randNum <= .75) {
// South
yy--;
} else {
// West
xx--;
}
numSteps++;
}
totalNumSteps += numSteps;
}
avgSteps = totalNumSteps / (1.0 * trials);
System.out.println("average number of steps = " + avgSteps);
}
}

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超17個(gè)贊
當(dāng)變量聲明遠(yuǎn)離其賦值或使用站點(diǎn)時(shí),往往會(huì)發(fā)生此類錯(cuò)誤。
使用Java Microbenchmark Harness(JMH)我無法看到重新分配和重新聲明變量之間的明顯性能優(yōu)勢(shì)。
Math.Random
但是,當(dāng)替換為RANDOM.nextInt(4)
和時(shí),我能夠看到巨大的(超過 2 倍的速度)switch
import java.util.Random;
public class RandomWalkers {
static final Random RANDOM = new Random();
public static void main(final String[] args) {
int r = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
int totalNumSteps = 0;
for (long i = 0; i < trials; i++) {
int x = 0;
int xx = 0;
int y = 0;
int yy = 0;
int numSteps = 0;
while (Math.abs(x - xx) + Math.abs(y - yy) != r) {
switch (RANDOM.nextInt(4)) {
case 0:
// North
yy++;
break;
case 1:
// East
xx++;
break;
case 2:
// South
yy--;
break;
default:
// West
xx--;
}
numSteps++;
}
totalNumSteps += numSteps;
}
double avgSteps = totalNumSteps / (1.0 * trials);
System.out.println("average number of steps = " + avgSteps);
}
}
P0.95 r = 40 的結(jié)果
重新分配:299.368 毫秒/操作
重新聲明RandomIntSwitch:139.107 毫秒/操作
我們可以做得更好
顯式if
條件雖然可讀性稍差,但(在這種情況下)比switch
此外,由于我們?cè)趩尉€程上下文中運(yùn)行,我們可以將 替換java.util.Random
為java.util.concurrent.ThreadLocalRandom
。
此外,顯式轉(zhuǎn)換double
比乘以更清晰,1.0
并為我們節(jié)省了兩個(gè)字節(jié)碼。
P0.95 r = 40 的結(jié)果
重新分配:299.368 毫秒/操作
重新聲明RandomIntSwitch:139.107 毫秒/操作
重新聲明ThreadLocalRandomIntIf:122.539 ms/op
下面的代碼快了將近 2.5 倍。
package com.stackoverflow.q56030483;
import java.util.concurrent.ThreadLocalRandom;
@SuppressWarnings("javadoc")
public class RandomWalker {
public static void main(final String[] args) {
int r = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
int totalNumSteps = 0;
final ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
for (long i = 0; i < trials; i++) {
int x = 0;
int xx = 0;
int y = 0;
int yy = 0;
int numSteps = 0;
while (Math.abs(x - xx) + Math.abs(y - yy) != r) {
final int direction= threadLocalRandom.nextInt(4);
// North
if (direction == 0) {
yy++;
// East
} else if (direction == 1) {
xx++;
// South
} else if (direction == 2) {
yy--;
// West
} else {
xx--;
}
numSteps++;
}
totalNumSteps += numSteps;
}
System.out.println("average number of steps = " + totalNumSteps / (double) trials);
}
}
Benchmark (arg) Mode Cnt Score Error Units
RandomWalkers.reassign 3 sample 37256 1.611 ± 0.002 ms/op
RandomWalkers.reassign:reassign·p0.00 3 sample 1.475 ms/op
RandomWalkers.reassign:reassign·p0.50 3 sample 1.593 ms/op
RandomWalkers.reassign:reassign·p0.90 3 sample 1.686 ms/op
RandomWalkers.reassign:reassign·p0.95 3 sample 1.780 ms/op
RandomWalkers.reassign:reassign·p0.99 3 sample 1.999 ms/op
RandomWalkers.reassign:reassign·p0.999 3 sample 2.507 ms/op
RandomWalkers.reassign:reassign·p0.9999 3 sample 4.367 ms/op
RandomWalkers.reassign:reassign·p1.00 3 sample 10.371 ms/op
RandomWalkers.reassign 10 sample 3528 17.029 ± 0.063 ms/op
RandomWalkers.reassign:reassign·p0.00 10 sample 15.548 ms/op
RandomWalkers.reassign:reassign·p0.50 10 sample 16.712 ms/op
RandomWalkers.reassign:reassign·p0.90 10 sample 18.416 ms/op
RandomWalkers.reassign:reassign·p0.95 10 sample 18.842 ms/op
RandomWalkers.reassign:reassign·p0.99 10 sample 20.690 ms/op
RandomWalkers.reassign:reassign·p0.999 10 sample 27.636 ms/op
RandomWalkers.reassign:reassign·p0.9999 10 sample 36.176 ms/op
RandomWalkers.reassign:reassign·p1.00 10 sample 36.176 ms/op
RandomWalkers.reassign 40 sample 227 268.714 ± 3.270 ms/op
RandomWalkers.reassign:reassign·p0.00 40 sample 251.134 ms/op
RandomWalkers.reassign:reassign·p0.50 40 sample 262.144 ms/op
RandomWalkers.reassign:reassign·p0.90 40 sample 296.223 ms/op
RandomWalkers.reassign:reassign·p0.95 40 sample 299.368 ms/op
RandomWalkers.reassign:reassign·p0.99 40 sample 303.416 ms/op
RandomWalkers.reassign:reassign·p0.999 40 sample 305.136 ms/op
RandomWalkers.reassign:reassign·p0.9999 40 sample 305.136 ms/op
RandomWalkers.reassign:reassign·p1.00 40 sample 305.136 ms/op
RandomWalkers.redeclareRandomIntSwitch 3 sample 69486 0.863 ± 0.001 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.00 3 sample 0.763 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.50 3 sample 0.843 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.90 3 sample 0.925 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.95 3 sample 1.028 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.99 3 sample 1.155 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.999 3 sample 1.721 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.9999 3 sample 5.181 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p1.00 3 sample 9.355 ms/op
RandomWalkers.redeclareRandomIntSwitch 10 sample 7072 8.485 ± 0.040 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.00 10 sample 7.668 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.50 10 sample 8.143 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.90 10 sample 9.650 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.95 10 sample 10.109 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.99 10 sample 11.960 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.999 10 sample 20.399 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.9999 10 sample 25.919 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p1.00 10 sample 25.919 ms/op
RandomWalkers.redeclareRandomIntSwitch 40 sample 466 130.302 ± 0.872 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.00 40 sample 123.732 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.50 40 sample 128.844 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.90 40 sample 135.083 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.95 40 sample 139.107 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.99 40 sample 155.153 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.999 40 sample 182.452 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p0.9999 40 sample 182.452 ms/op
RandomWalkers.redeclareRandomIntSwitch:redeclareRandomIntSwitch·p1.00 40 sample 182.452 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf 40 sample 96 107.953 ± 2.148 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.00 40 sample 99.746 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.50 40 sample 107.676 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.90 40 sample 113.797 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.95 40 sample 122.539 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.99 40 sample 130.810 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.999 40 sample 130.810 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p0.9999 40 sample 130.810 ms/op
RandomWalkers.redeclareThreadLocalRandomIntIf:redeclareThreadLocalRandomIntIf·p1.00 40 sample 130.810 ms/op
添加回答
舉報(bào)