2016-02-17 16 views
5

Quindi ecco la cosa semplice che sto provando a testare, cos'è un'operazione di mod più veloce o un AND (assumendo la potenza di due) - questo è ciò che hashMap internamente. È un "test" scritto correttamente? Devo ammettere che la parte interna di jmh e la possibilità di scrivere un micro benchmark corretto dopo aver esaminato tutti i campioni (per la terza volta credo) è una vera sfida. :)Come benchmark '&' vs '%' costano correttamente, usando JMH

@State(Scope.Thread) 
@BenchmarkMode(org.openjdk.jmh.annotations.Mode.AverageTime) 
@OutputTimeUnit(TimeUnit.NANOSECONDS) 
public class MeasureSpeedModuleVsAnd { 

    public static void main(String[] args) throws Exception { 
     Options opt = new OptionsBuilder() 
       .include(MeasureSpeedModuleVsAnd.class.getSimpleName()) 
       .forks(1) 
       .warmupIterations(1) 
       .measurementIterations(5) 
       .warmupTime(TimeValue.seconds(2)) 
       .build(); 

     new Runner(opt).run(); 

    } 

    @Param({ "16", "32", "256", "1048576" /* 2 power of 10 */ }) 
    public int number_of_buckets; 

    @Param({ "345984", "123456", "111", "98653" }) 
    public int hashcode; 

    @Benchmark 
    public int benchamark_modulo() { 
     return hashcode % number_of_buckets; 
    } 

    @Benchmark 
    public int benchmark_and() { 
     return (number_of_buckets - 1) & hashcode; 
    } 
} 
+3

Beh, certo che no, 'arg% 33'! =' (Arg - 1) & 33'. Prendi '42' come esempio ... –

+0

Volevi scrivere' arg% 32' e 'arg & (32 - 1)'? –

+0

@AlekseyShipilev totalmente mio cattivo, copiato il codice sbagliato. – Eugene

risposta

4

Questo è spiegato in dettaglio in questo post del blog: http://psy-lob-saw.blogspot.co.za/2014/11/the-mythical-modulo-mask.html

Il vostro punto di riferimento è rotto (confrontando quello che sembra quantità irrilevanti), perché si sta confrontando (non_final_field & costante) con (% non_final_field costante). Sostituire con (non_final_field1% non_final_field2) e (non_final_field1 & (non_final_field2-1)) dove non_final_field2 è una potenza di 2.

Nel contesto HashMap il valore viene utilizzato per leggere da un array e il post copre le implicazioni anche da quel lato.