2015-06-01 17 views
6

Ho usato questo benchmark java8-lambda-performance-test e durante l'esecuzione di esso ho fatto i seguenti:Impatto di Intrinsics e inlining sulle prestazioni di Lambda?

1.Disabled utilizzo intrinseca

2.Disabled inlining

3.Disabled Compilazione modalità

I ho scoperto che disabilitare le prime due ottimizzazioni non ha alcun effetto sui risultati.

che è strano, e anche quando si esegue il punto di riferimento con la stampa e intrinseca, non ho trovato alcuna chiamata al intrinseca compiledLambdaForm

Dal intrinseci matematica sono molto utilizzati lì _min, _pow ... mi aspettavo che la disabilitazione di elementi intrinseci avrebbe rallentato le prestazioni

+1

Belle dichiarazioni dei risultati. Se questo è un problema, spiega chiaramente perché e cosa ti saresti aspettato. Altrimenti non ho visto nessun problema. –

+0

Ho modificato il mio post – Bionix1441

+0

Dando un'occhiata all'articolo tutto quello che posso dire è che è piuttosto vecchio (17 marzo 2014). Ci sono stati aggiornamenti di Java 8 da questo articolo. Se stai utilizzando una versione JVM diversa da quella usata dall'autore (che non dichiara), allora è abbastanza comprensibile che i tuoi test mostrino risultati diversi. Prova a utilizzare un Java 8 e vedere se questo fa alcuna differenza. –

risposta

4

Il motivo per cui non si è notato un effetto prestazionale atteso è poorly written benchmark.
Ho riscritto il benchmark utilizzando JMH e le cose finalmente sono andate bene.

package lambdademo; 

import org.openjdk.jmh.annotations.*; 

import java.util.List; 

@State(Scope.Benchmark) 
public class LambdaBenchmark { 
    @Param("100") 
    private static int loopCount; 

    private static double identity(double val) { 
     double result = 0; 
     for (int i=0; i < loopCount; i++) { 
      result += Math.sqrt(Math.abs(Math.pow(val, 2)));  
     } 
     return result/loopCount; 
    } 

    private List<EmployeeRec> employeeList = new EmployeeFile().loadEmployeeList(); 

    @Benchmark 
    public double streamAverage() { 
     return streamAverageNoInline(); 
    } 

    @Benchmark 
    @Fork(jvmArgs = "-XX:-Inline") 
    public double streamAverageNoInline() { 
     return employeeList.stream() 
       .filter(s -> s.getGender().equals("M")) 
       .mapToDouble(s -> s.getAge()) 
       .average() 
       .getAsDouble(); 
    } 

    @Benchmark 
    public double streamMath() { 
     return streamMathNoIntrinsic(); 
    } 

    @Benchmark 
    @Fork(jvmArgs = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DisableIntrinsic=_dpow,_dabs,_dsqrt"}) 
    public double streamMathNoIntrinsic() { 
     return employeeList.stream() 
       .filter(s -> s.getGender().equals("M")) 
       .mapToDouble(s -> identity(s.getAge())) 
       .average() 
       .getAsDouble(); 
    } 
} 

Ecco i risultati:

Benchmark        Mode Cnt  Score Error Units 
LambdaBenchmark.streamAverage   avgt 5 71,490 ± 0,770 ms/op 
LambdaBenchmark.streamAverageNoInline avgt 5 122,740 ± 0,576 ms/op 
LambdaBenchmark.streamMath    avgt 5 92,672 ± 1,538 ms/op 
LambdaBenchmark.streamMathNoIntrinsic avgt 5 5747,007 ± 20,387 ms/op 

Come previsto, il punto di riferimento con -XX:-Inline lavora il 70% più a lungo, e la versione con la matematica intrinseche disabile sembra essere 60 volte più lento!

+0

Una domanda: Perché hai codificato 'private static int loopCount = Integer.getInteger ("loopCount", 100); 'invece di' int loopCount = 100; ' – Bionix1441

+2

Inoltre, yu no' @ Param'? Funziona anche su campi statici. –

+2

@ Bionix1441 Non c'è una ragione particolare per quello. In entrambi i casi lo farò. @AlekseyShipilev Right, '@ Param' è migliore. Ho aggiornato il codice. – apangin

1

Non penso che ci sia alcun effetto degli intrinsechi, perché le espressioni Lambda utilizzano principalmente la classe LambdaMetaFactory. Ecco perché sia ​​l'inlining che l'intrinseco non hanno alcun effetto sul lambda stesso.

Ora per gli intrinseci matematica Il mio credo è che dal momento che vengono utilizzati solo nel metodo di identità, che viene utilizzato solo in caso di LambdaExtraAverage e LambdaExtraSerial test allora non influenzeranno molto i risultati dei benchmark.

Problemi correlati