Tengo un gran problema al evaluar mi código de Java. Para simplificar el problema, escribí el siguiente código que produce el mismo comportamiento curioso. Importante es el método run() y la tasa de valor doble dada. Para mi prueba de tiempo de ejecución (en el método principal) configuré la tasa a 0.5 una vez y 1.0 la otra vez. Con el valor 1.0, la sentencia if se ejecutará en cada iteración de ciclo y con el valor 0.5 la instrucción if se ejecutará la mitad. Por esta razón, esperaba un tiempo de ejecución más prolongado para el primer caso, pero lo contrario es cierto. ¿Alguien puede explicarme este fenómeno?Java curioso Loop Performance
El resultado de principal:
Test mit rate = 0.5
Length: 50000000, IF executions: 25000856
Execution time was 4329 ms.
Length: 50000000, IF executions: 24999141
Execution time was 4307 ms.
Length: 50000000, IF executions: 25001582
Execution time was 4223 ms.
Length: 50000000, IF executions: 25000694
Execution time was 4328 ms.
Length: 50000000, IF executions: 25004766
Execution time was 4346 ms.
=================================
Test mit rate = 1.0
Length: 50000000, IF executions: 50000000
Execution time was 3482 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3572 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3529 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3479 ms.
Length: 50000000, IF executions: 50000000
Execution time was 3473 ms.
El Código
public ArrayList<Byte> list = new ArrayList<Byte>();
public final int LENGTH = 50000000;
public PerformanceTest(){
byte[]arr = new byte[LENGTH];
Random random = new Random();
random.nextBytes(arr);
for(byte b : arr)
list.add(b);
}
public void run(double rate){
byte b = 0;
int count = 0;
for (int i = 0; i < LENGTH; i++) {
if(getRate(rate)){
list.set(i, b);
count++;
}
}
System.out.println("Length: " + LENGTH + ", IF executions: " + count);
}
public boolean getRate(double rate){
return Math.random() < rate;
}
public static void main(String[] args) throws InterruptedException {
PerformanceTest test = new PerformanceTest();
long start, end;
System.out.println("Test mit rate = 0.5");
for (int i = 0; i < 5; i++) {
start=System.currentTimeMillis();
test.run(0.5);
end = System.currentTimeMillis();
System.out.println("Execution time was "+(end-start)+" ms.");
Thread.sleep(500);
}
System.out.println("=================================");
System.out.println("Test mit rate = 1.0");
for (int i = 0; i < 5; i++) {
start=System.currentTimeMillis();
test.run(1.0);
end = System.currentTimeMillis();
System.out.println("Execution time was "+(end-start)+" ms.");
Thread.sleep(500);
}
}
Probablemente algo que ver con [predicción de saltos (mal)] (http://stackoverflow.com/questions/11227809/why- is-processing-a-sorted-array-faster-an-unsorted-array). – assylias
El azar es bastante lento aquí. Te sugiero que sigas una progresión simple y no gastarás la mayor parte de tu tiempo generando números aleatorios. Sugiero que alterne las pruebas en lugar de ejecutar una muchas veces y ejecutar una segunda muchas veces. (No es necesario que duerma entre ellos) –
pensando en calentar ¿qué ocurre si primero ejecuta el 1.0? – ssedano