public static void mapStreamIncrementDemo(int cycles, int size) {
int[] numbers = new int[size];
Arrays.setAll(numbers, j -> j);
long start = System.currentTimeMillis();
for (int i = 0; i < cycles; i++) {
Arrays.stream(numbers).filter(v -> v % 2 == 0).reduce(0, (a, b) -> a + b);
}
Integer evenSum = Arrays.stream(numbers).filter(v -> v % 2 == 0).reduce(0, (a, b) -> a + b);
long end = System.currentTimeMillis();
System.out.println("map stream, array length = " + numbers.length + ", evenSum = " + evenSum + ", time = " + (end - start) + "ms");
}
Den gleichen Algorithmus programmieren wir mit dem klassischen for-Loop über die Methode mapForIncrementDemo:public static void mapForIncrementDemo(int cycles, int size) {
int[] numbers = new int[size];
Arrays.setAll(numbers, j -> j);
long start = System.currentTimeMillis();
for (int i = 0; i < cycles; i++) {
int evenSum = 0;
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] % 2 == 0) {
evenSum += numbers[j];
}
}
}
long end = System.currentTimeMillis();
int evenSum = 0;
for (int j = 0; j < numbers.length; j++) {
numbers[j] = j;
if (numbers[j] % 2 == 0) {
evenSum += numbers[j];
}
}
System.out.println("map increment, array length = " + numbers.length + ", evenSum = " + evenSum + ", time = " + (end - start) + "ms");
}
Die Zeit messen wir über die Methode System.currentTimeMillis() jeweils am Anfang und am Ende. Default arbeiten wir mit einem Array der Länge 100. Das folgenden Listing zeigt die Methode main:public static void main(String[] args) {
int cycles = 1000000;
int size = 100;
if (args.length > 0) {
size = Integer.parseInt(args[0]);
}
mapStreamIncrementDemo(cycles, size);
mapForIncrementDemo(cycles, size);
}
mit dem entsprechenden Chart Diagramm:
Klar schneller ist die Variante mit dem klassischen for Loop.
mit dem entsprechenden Chart Diagramm:
Der klassische for Loop ist noch marginal schneller und beide praktisch gleichauf.
mit dem entsprechenden Chart Diagramm:
Die Variante Stream ist leicht schneller.
package main
import (
"fmt"
"os"
"strconv"
"time"
)
func main() {
cycles := 1000000
size := 10
if len(os.Args) > 1 {
size, _ = strconv.Atoi(os.Args[1])
}
numbers := make([]int, size)
for i := 0; i < size; i++ {
numbers[i] = i
}
start := makeTimestamp()
for i := 0; i < cycles; i++ {
evenSum := 0
for j := 0; j < size; j++ {
if numbers[j]%2 == 0 {
evenSum += numbers[j]
}
}
}
evenSum := 0
for j := 0; j < size; j++ {
if numbers[j]%2 == 0 {
evenSum += numbers[j]
}
}
end := makeTimestamp()
fmt.Printf("\nsize = %d, evenSum= %d, time = %d ms\n", size, evenSum, (end - start))
}
func makeTimestamp() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
}
Die gemessenen Zeiten sprechen für go:mit dem entsprechenden Chart Diagramm:
go ist damit praktisch doppelt so schnell wie die gleiche Lösung in Java.