提供的示例程序用于计算数组中小于指定值的元素数。 程序所花费的处理时间各不相同,使用Java 8 forEach和stream需要更多时间来执行。请解释一下我是否应该使用Java 8功能,如果没有应该避免哪些方面,还可以使用parallelStream或多核处理器来支持多核处理器吗?
代码:
public static void main(String[] args) {
int lessThan = 4;
// Using for loop iteration
List<Integer> integerForSort1 = Arrays.asList(4, 1, 1, 2, 3);
long startTime1 = System.nanoTime();
long count1 = countNumbers(integerForSort1, lessThan);
long stopTime1 = System.nanoTime();
System.out.println(stopTime1 - startTime1);
System.out.println(count1);
integerForSort1 = null;
System.gc();
// Using binary search
List<Integer> integerForSort2 = Arrays.asList(4, 1, 1, 2, 3);
long startTime2 = System.nanoTime();
long count2 = countByBinarySearch(integerForSort2, lessThan);
long stopTime2 = System.nanoTime();
System.out.println(stopTime2 - startTime2);
System.out.println(count2);
integerForSort2 = null;
System.gc();
// Using Java 8
List<Integer> integerForSort3 = Arrays.asList(4, 1, 1, 2, 3);
long startTime3 = System.nanoTime();
long count3 = integerForSort3.stream()
.filter(p -> p < lessThan)
.count();
long stopTime3 = System.nanoTime();
System.out.println(stopTime3 - startTime3);
System.out.println(count3);
integerForSort3 = null;
System.gc();
//Using Java 8 for each loop
List<Integer> integerForSort4 = Arrays.asList(4, 1, 1, 2, 3);
long startTime4 = System.nanoTime();
long count4 = process(integerForSort4, p -> p < lessThan);
long stopTime4 = System.nanoTime();
System.out.println(stopTime4 - startTime4);
System.out.println(count4);
integerForSort4 = null;
}
public static long countNumbers(List<Integer> integerForSort, int lessThan) {
long count = 0;
Collections.sort(integerForSort);
for (Integer anIntegerForSort : integerForSort) {
if (anIntegerForSort < lessThan)
count++;
}
return count;
}
public static long countByBinarySearch(List<Integer> integerForSort, int lessThan){
if(integerForSort==null||integerForSort.isEmpty())
return 0;
int low = 0, mid = 0, high = integerForSort.size();
Collections.sort(integerForSort);
while(low != high){
mid = (low + high) / 2;
if (integerForSort.get(mid) < lessThan) {
low = mid + 1;
}
else {
high = mid;
}
}
return low;
}
public static long process(List<Integer> integerForSort, Predicate<Integer> predicate) {
final AtomicInteger i = new AtomicInteger(0);
integerForSort.forEach((Integer p) -> {
if (predicate.test(p)) {
i.getAndAdd(1);
}
});
return i.intValue();
}
输出:
345918
4
21509
4
29651234
4
2242999
4
问题:
Is it possible to reduce the process time using Java 8 features?
Why does Java 8 stream takes more time?
How can I use lambda expression with binary Search, will it process faster?
即使对concurrent.ExecutorService使用多线程也能得到一致的结果:
Result 4 : Thread 'pool-1-thread-1' ran process - Using Java 8 stream in 6 millisecond, from 11:16:05:361 to 11:16:05:367
Result 4 : Thread 'pool-1-thread-2' ran process - Using Java 8 forEach in 3 millisecond, from 11:16:05:361 to 11:16:05:364
Result 4 : Thread 'pool-1-thread-4' ran process - Using Java 7 binary Search in 0 millisecond, from 11:16:05:379 to 11:16:05:379
Result 4 : Thread 'pool-1-thread-3' ran process - Using Java 7 for loop in 1 millisecond, from 11:16:05:362 to 11:16:05:363
答案 0 :(得分:1)
我不知道答案,因为我没有进行任何测试,但我认为,5个元素的性能测试没有诊断价值,而且毫无意义。您应该生成10s,100s或数百mils的数组,以查看性能差异。
Java 8会创建多个对象,这会导致与简单for循环相反的开销。因此,只有5个测试元素,您的结果取决于初始化执行所需的工作量。
你知道,CPU上的5个数字相乘甚至比将其复制到GPU内存要快,所以即使在GPU开始计算之前你也可以在CPU上获得结果。但是如果你的数据增长并且你的GPU平行增加了数百个数字,你就会看到速度差异。