Я читаю «Java 8 in Action» (Рауль-Габриэль Урма, Марио Фуско и Алан Майкрофт), раздел 5.6.3, страницы 116 и 117. Представленный код обрабатывает вычисления так называемых «Пифагорейские троицы». Страница 116 показывает первую попытку, а на стр. 117 показана улучшенная попытка создания этих троек, где оба используют метод «.rangeClosed()».Оптимизация числа числовых потоков
Я нашел некоторые оптимизации, выходящие за рамки книги, и я хотел бы поделиться ими здесь. Я сделал несколько простых «System.currentTimeMillis()» вычислений, чтобы увидеть, были ли мои модификации усовершенствованиями, и они оказались немного лучше, чем в книге. Можете ли вы предоставить улучшенные улучшения, объяснения или показатели для этого кода?
public void test() {
long time1 = System.currentTimeMillis();
/*
* From text, page 116
*/
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
.mapToObj(b -> new int[]{a, b, (int)Math.sqrt(a*a + b*b)})
)
.forEach(c -> System.out.println("["+c[0]+" "+c[1]+" "+c[2]+"]"));
long time2 = System.currentTimeMillis();
System.out.println();
long time3 = System.currentTimeMillis();
/*
* From text, page 117, I added "map(...)" so that end result are ints, not doubles
*/
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(b -> new double[]{a, b, Math.sqrt(a*a + b*b)})
.filter(t -> t[2] % 1 == 0)
.map(b -> new int[]{(int)b[0], (int)b[1], (int)b[2]})
)
.forEach(c -> System.out.println("["+c[0]+" "+c[1]+" "+c[2]+"]"));
long time4 = System.currentTimeMillis();
System.out.println();
long time5 = System.currentTimeMillis();
/*
* My optimization attempt #1: now mapToObj(...) has c%1!=0 conditional, filter checks array element not null
*/
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(b -> {
double c = Math.sqrt(a*a + b*b);
return new Object[]{a, b, c % 1 == 0 ? (int)c : null};
})
.filter(d -> d[2] != null)
.map(e -> new int[]{(int)e[0], (int)e[1], (int)e[2]})
)
.forEach(f -> System.out.println("["+f[0]+" "+f[1]+" "+f[2]));
long time6 = System.currentTimeMillis();
System.out.println();
long time7 = System.currentTimeMillis();
/*
* My optimization attempt #2: now mapToObj(...) has c%1!=0 conditional, filter checks "array element" not 0
*/
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(b -> {
double c = Math.sqrt(a*a + b*b);
return new int[]{a, b, c % 1 == 0 ? (int)c : 0 };
})
.filter(t -> t[2] != 0)
)
.forEach(d -> System.out.println("["+d[0]+" "+d[1]+" "+d[2]+"]"));
long time8 = System.currentTimeMillis();
System.out.println();
long time9 = System.currentTimeMillis();
/*
* My optimization attempt #3: now mapToObj(...) has c%1!=0 conditional, filter checks "collection element" not null
*/
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a -> IntStream.rangeClosed(a, 100)
.mapToObj(b -> {
double c = Math.sqrt(a*a + b*b);
return (c % 1 != 0) ? null : new int[]{a, b, (int)c};
})
.filter(t -> t != null)
)
.forEach(d -> System.out.println("["+d[0]+" "+d[1]+" "+d[2]+"]"));
long time10 = System.currentTimeMillis();
System.out.println();
long timeDelta1 = time2 - time1;
long timeDelta2 = time4 - time3;
long timeDelta3 = time6 - time5;
long timeDelta4 = time8 - time7;
long timeDelta5 = time10 - time9;
System.out.println("timeDelta1: " + timeDelta1 + ", timeDelta2: " + timeDelta2 + ", timeDelta3: " + timeDelta3 + ", timeDelta4: " + timeDelta4 + ", timeDelta5: " + timeDelta5);
}
public static void main(String[] args){
ReduceTest reduceTest = new ReduceTest();
reduceTest.test();
}
ПРИМЕЧАНИЕ: Кажется, что вы можете использовать «return;» в методе «.forEach()», но не в методе «.mapToInt()». Использование «return;» в lambda, прошедшем в метод .mapToInt(), будет устранена необходимость использования метода «.filter()». Похоже, это будет улучшение потоков api.
Я думаю, этот вопрос лучше обсудить на: http://codereview.stackexchange.com/ – Flown
@Flown, хороший момент, я это сделал. –
@Alexis, спасибо, что тег потока должен быть java-потоком, вы правы, конечно. –