Hi,
ich habe einen Benchmark geschrieben der ueber Listen iteriert. Hierbei unterscheide ich zwei Arten von Iterationen:
1. via Listen-Index
2. via implizitem Iterator (also foreach-Schleife)
Auch teste ich ob es einen Unterschied macht ob die Benchmark-Methode den Original-Typ entgegennimmt (also z.B. ArrayList) oder stattdessen den Typ "List" akzeptiert.
Hier die Ergebnisse in Millisekunden und den Benchmark-Code den man sich anschauen sollte um es vollstaendig zu kapieren:
indexedIterationArrayList: 67917
indexedIterationCopyOnWriteArrayList: 119210
indexedIterationAList: 59484
indexedIterationCList: 119701
indexedIterationUnmodifiableList: 57325
implicitIiteratorArrayList: 80103
implicitIiteratorCopyOnWriteArrayList: 61323
implicitIiteratorAList: 89433
implicitIiteratorCList: 67278
implicitIiteratorUnmodifiableList: 79405
Am schnellsten ist UnmodifiableList bei indexed-Iteration.
Wie man sieht ist index-Iteration schneller als foreach bei ArrayList. Lustigerweise macht es einen Unterschied ob die Benchmark-Methode ArrayList oder List entgegennimmt. Beim indexed-Iterator ist es schneller wenn man List anstatt ArrayList in der Signatur stehen hat. Beim foreach-Iterator ist es genau anderstrum.
CopyOnWriteArrayList ist langsamer als ArrayList beim indexed-Iterator (was mich ueberrascht hat). Beim foreach-Iterator ist CopyOnWriteArrayList schneller als ArrayList. Auch sehr ueberraschend. UnmodifiableList ist nicht schneller als ArrayList.
Wie soll man das alles erklaeren?
ich habe einen Benchmark geschrieben der ueber Listen iteriert. Hierbei unterscheide ich zwei Arten von Iterationen:
1. via Listen-Index
2. via implizitem Iterator (also foreach-Schleife)
Auch teste ich ob es einen Unterschied macht ob die Benchmark-Methode den Original-Typ entgegennimmt (also z.B. ArrayList) oder stattdessen den Typ "List" akzeptiert.
Hier die Ergebnisse in Millisekunden und den Benchmark-Code den man sich anschauen sollte um es vollstaendig zu kapieren:
indexedIterationArrayList: 67917
indexedIterationCopyOnWriteArrayList: 119210
indexedIterationAList: 59484
indexedIterationCList: 119701
indexedIterationUnmodifiableList: 57325
implicitIiteratorArrayList: 80103
implicitIiteratorCopyOnWriteArrayList: 61323
implicitIiteratorAList: 89433
implicitIiteratorCList: 67278
implicitIiteratorUnmodifiableList: 79405
Am schnellsten ist UnmodifiableList bei indexed-Iteration.
Wie man sieht ist index-Iteration schneller als foreach bei ArrayList. Lustigerweise macht es einen Unterschied ob die Benchmark-Methode ArrayList oder List entgegennimmt. Beim indexed-Iterator ist es schneller wenn man List anstatt ArrayList in der Signatur stehen hat. Beim foreach-Iterator ist es genau anderstrum.
CopyOnWriteArrayList ist langsamer als ArrayList beim indexed-Iterator (was mich ueberrascht hat). Beim foreach-Iterator ist CopyOnWriteArrayList schneller als ArrayList. Auch sehr ueberraschend. UnmodifiableList ist nicht schneller als ArrayList.
Wie soll man das alles erklaeren?
Java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
public class PerformanceComparison {
private static final boolean DEBUG = true;
static int indexedIterationArrayList = 0;
static int indexedIterationCopyOnWriteArrayList = 0;
static int indexedIterationAList = 0;
static int indexedIterationCList = 0;
static int indexedIterationUnmodifiableList = 0;
static int implicitIiteratorArrayList = 0;
static int implicitIiteratorCopyOnWriteArrayList = 0;
static int implicitIiteratorAList = 0;
static int implicitIiteratorCList = 0;
static int implicitIiteratorUnmodifiableList = 0;
public static void main(String[] args) {
int repeats = 1000;
final int size = 100000000;
ArrayList<Integer> arraylist = new ArrayList<>(size);
Random random = new Random();
for (int i = 0; i < size; i++) {
arraylist.add(random.nextInt(100));
}
System.out.println(arraylist.size());
CopyOnWriteArrayList<Integer> cow = new CopyOnWriteArrayList<>(arraylist);
List<Integer> unmodifiableList = Collections.unmodifiableList(arraylist);
for (int i = 0; i < repeats; i++) {
indexedIterationArrayList(arraylist);
indexedIterationCopyOnWriteArrayList(cow);
indexedIterationAList(arraylist);
indexedIterationCList(cow);
indexedIterationUnmodifiableList(unmodifiableList);
implicitIiteratorArrayList(arraylist);
implicitIiteratorCopyOnWriteArrayList(cow);
implicitIiteratorAList(arraylist);
implicitIiteratorCList(cow);
implicitIiteratorUnmodifiableList(unmodifiableList);
}
System.out.println("indexedIterationArrayList: " + indexedIterationArrayList);
System.out.println("indexedIterationCopyOnWriteArrayList: " + indexedIterationCopyOnWriteArrayList);
System.out.println("indexedIterationAList: " + indexedIterationAList);
System.out.println("indexedIterationCList: " + indexedIterationCList);
System.out.println("indexedIterationUnmodifiableList: " + indexedIterationUnmodifiableList);
System.out.println("implicitIiteratorArrayList: " + implicitIiteratorArrayList);
System.out.println("implicitIiteratorCopyOnWriteArrayList: " + implicitIiteratorCopyOnWriteArrayList);
System.out.println("implicitIiteratorAList: " + implicitIiteratorAList);
System.out.println("implicitIiteratorCList: " + implicitIiteratorCList);
System.out.println("implicitIiteratorUnmodifiableList: " + implicitIiteratorUnmodifiableList);
}
// indexedIteration
public static void indexedIterationArrayList(ArrayList<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < list.size(); ++i) {
sum += list.get(i);
}
indexedIterationArrayList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void indexedIterationCopyOnWriteArrayList(CopyOnWriteArrayList<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < list.size(); ++i) {
sum += list.get(i);
}
indexedIterationCopyOnWriteArrayList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void indexedIterationAList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < list.size(); ++i) {
sum += list.get(i);
}
indexedIterationAList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void indexedIterationCList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < list.size(); ++i) {
sum += list.get(i);
}
indexedIterationCList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void indexedIterationUnmodifiableList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < list.size(); ++i) {
sum += list.get(i);
}
indexedIterationUnmodifiableList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
// foreach (a.k.a. implicit iterator)
public static void implicitIiteratorArrayList(ArrayList<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (Integer a : list) {
sum += a;
}
implicitIiteratorArrayList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void implicitIiteratorCopyOnWriteArrayList(CopyOnWriteArrayList<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (Integer a : list) {
sum += a;
}
implicitIiteratorCopyOnWriteArrayList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void implicitIiteratorAList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (Integer a : list) {
sum += a;
}
implicitIiteratorAList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void implicitIiteratorUnmodifiableList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (Integer a : list) {
sum += a;
}
implicitIiteratorUnmodifiableList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
public static void implicitIiteratorCList(List<Integer> list) {
long start = System.currentTimeMillis();
int sum = 0;
for (Integer a : list) {
sum += a;
}
implicitIiteratorCList += System.currentTimeMillis() - start;
if (DEBUG) System.out.println(sum);
}
}