This non è un duplicato della mia domanda. L'ho controllato ed è più sulle classi anonime interiori.Differenza nelle prestazioni lambda?
ero curioso di sapere le espressioni lambda e verificato le seguenti:
- dato un array di diecimila voci, quale sarebbe il più veloce per cancellare alcuni indici: espressione Lamba o Per-Loop con un caso di test interno ?
I primi risultati non sono stati sorprendenti nel fatto che non sapevo cosa stavo andando a venire con:
final int NUMBER_OF_LIST_INDEXES = 10_000;
List<String> myList = new ArrayList<>();
String[] myWords = "Testing Lamba expressions with this String array".split(" ");
for (int i = 0 ; i < NUMBER_OF_LIST_INDEXES ; i++){
myList.add(myWords[i%6]);
}
long time = System.currentTimeMillis();
// BOTH TESTS WERE RUN SEPARATELY OF COURSE
// PUT THE UNUSED ONE IN COMMENTS WHEN THE OTHER WAS WORKING
// 250 milliseconds for the Lambda Expression
myList.removeIf(x -> x.contains("s"));
// 16 milliseconds for the traditional Loop
for (int i = NUMBER_OF_LIST_INDEXES - 1 ; i >= 0 ; i--){
if (myList.get(i).contains("s")) myList.remove(i);
}
System.out.println(System.currentTimeMillis() - time + " milliseconds");
Ma poi, ho deciso di cambiare la costante NUMBER_OF_LIST_INDEXES
a un milione e qui è il risultato:
final int NUMBER_OF_LIST_INDEXES = 1_000_000;
List<String> myList = new ArrayList<>();
String[] myWords = "Testing Lamba expressions with this String array".split(" ");
for (int i = 0 ; i < NUMBER_OF_LIST_INDEXES ; i++){
myList.add(myWords[i%6]);
}
long time = System.currentTimeMillis();
// BOTH TESTS WERE RUN SEPARATELY OF COURSE
// PUT THE UNUSED ONE IN COMMENTS WHEN THE OTHER WAS WORKING
// 390 milliseconds for the Lambda Expression
myList.removeIf(x -> x.contains("s"));
// 32854 milliseconds for the traditional Loop
for (int i = NUMBER_OF_LIST_INDEXES - 1 ; i >= 0 ; i--){
if (myList.get(i).contains("s")) myList.remove(i);
}
System.out.println(System.currentTimeMillis() - time + " milliseconds");
per rendere le cose più semplici da leggere, ecco i risultati:
| | 10.000 | 1.000.000 |
| LAMBDA | 250ms | 390ms | 156% evolution
|FORLOOP | 16ms | 32854ms | 205000+% evolution
Ho le seguenti domande:
Qual è la magia dietro questo? Come arriviamo a una così grande differenza per l'array e non per il lambda quando gli indici con cui lavorare è * 100.
In termini di prestazioni, come sappiamo quando utilizzare Lambdas e quando attenersi ai metodi tradizionali per lavorare con i dati?
Si tratta di un comportamento specifico del metodo
List
? Un'altra espressione Lambda produce anche esibizioni casuali come questa?
Stai potrebbero essere oggetto di indurre in errore da anomalie micro-analisi comparativa. Leggi questo: http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java –
puoi controllare il codice sorgente di ArrayList.removeIf (filtro) – andy
se non l'hai fatto, configura il tuo IDE per mostrare i sorgenti JDK così puoi fare le tue ricerche. [Eclipse] (http://stackoverflow.com/a/426131/1362755), [Netbeans] (http://stackoverflow.com/a/11071313/1362755) – the8472