Java8 Parallel Stream花费时间对值进行求和
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java8 Parallel Stream花费时间对值进行求和,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3866字,纯文字阅读大概需要6分钟。
内容图文
![Java8 Parallel Stream花费时间对值进行求和](/upload/InfoBanner/zyjiaocheng/806/b8c878c807824dc4bf7bbbf1506c2d94.jpg)
我正在练习java8并行流部分并编写一个程序,它将从0传递给参数的数字加到该数字.
例如,如果我通过10,它将从1到10的数字相加并返回输出.
以下是该计划
public class ParellelStreamExample {
public static void main(String[] args) {
System.out.println("Long Range value - "+ Long.MIN_VALUE + " to "+ Long.MAX_VALUE);
long startTime = System.nanoTime();
long sum = sequentailSum(100000000);
System.out.println(
"Time in sequential execution " + (System.nanoTime() - startTime) / 1000000 + " msec with sum = " + sum);
long startTime1 = System.nanoTime();
long sum1 = parellelSum(100000000);
System.out.println("Time in parallel execution " + (System.nanoTime() - startTime1) / 1000000
+ " msec with sum = " + sum1);
}
private static Long parellelSum(long n) {
return Stream.iterate(1l, i -> i + 1).limit(n).parallel().reduce(0L, Long::sum);
}
private static Long sequentailSum(long n) {
return Stream.iterate(1l, i -> i + 1).limit(n).reduce(0L, Long::sum);
}
}
我收到的输出是
Long Range value - -9223372036854775808 to 9223372036854775807
Time in sequential execution 1741 msec with sum = 5000000050000000
Exception in thread "main" java.lang.OutOfMemoryError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
at java.util.stream.SliceOps$1.opEvaluateParallelLazy(SliceOps.java:155)
at java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:431)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:474)
at com.abhishek.javainaction.stream.parellel.ParellelStreamExample.parellelSum(ParellelStreamExample.java:21)
at com.abhishek.javainaction.stream.parellel.ParellelStreamExample.main(ParellelStreamExample.java:14)
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.Long.valueOf(Long.java:840)
at com.abhishek.javainaction.stream.parellel.ParellelStreamExample.lambda$0(ParellelStreamExample.java:21)
at com.abhishek.javainaction.stream.parellel.ParellelStreamExample$$Lambda$3/250421012.apply(Unknown Source)
at java.util.stream.Stream$1.next(Stream.java:1033)
at java.util.Spliterators$IteratorSpliterator.trySplit(Spliterators.java:1784)
at java.util.stream.AbstractShortCircuitTask.compute(AbstractShortCircuitTask.java:114)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
为什么这个程序不能并行运行部分和gc开销,
相反,它应该在并行部分运行得更快,因为它使用fork / join框架并通过线程进行处理.
它出了什么问题?
解决方法:
这里有几件事情出了问题.
>您正在尝试使用System.nanoTime()而不是JMH之类的代码来对代码进行基准测试.
>你试图在Long上计算一个简单的计算(总和),而不是使用LongStream.如果JVM无法摆脱装箱,那么指针追逐的开销很容易淹没并行性的好处.
>您正在尝试对由iterate生成的继承顺序流进行分析.流框架将尝试通过缓冲流并将其分派给多个线程来执行您所要求的操作,这会增加大量开销.
>您正在对有序并行流使用限制.这要求流框架执行大量额外同步,以确保使用n个第一个元素来生成结果.您将看到,如果将.unordered()放在并行流中,执行时间将显着减少,但结果将是非确定性的,因为您将得到一些n个元素的总和,而不是前n个元素.
正确的方法是使用JMH并用LongStream.rangeClosed(1,n)替换iterate(…).limit(…)
内容总结
以上是互联网集市为您收集整理的Java8 Parallel Stream花费时间对值进行求和全部内容,希望文章能够帮你解决Java8 Parallel Stream花费时间对值进行求和所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。