一心多用是我的拿手好戏。当我在写这篇博客的时候,我还在为昨天聚会上说过的话感到尴尬,当时大家看我跟看怪物一样。好吧,不过所幸的是我并不孤单——Java 8它也很擅长这口。来看下它是怎么回事。
Java 8中一个关键的新特性就是它支持并行数组操作。你可以使用lambda表达式来进行排序,过滤,分组等操作,它能自动的发挥多核架构的优势。带来的好处就是作为一名Java开发人员,你只需很小的工作量就可以立马获得性能的提升。相当酷的功能。
那么问题来了——它到底能有多快,我该在什么时候使用它?答案可能会让人有些失望——这得具体情况具体分析。想知道决定因素是什么吗?继续往下看就知道了。
新的API
Java 8的新的并行操作的API非常巧妙。我们来看下准备进行测试的几个接口:
1. 通过这个接口可以发挥多处理器的优势进行并行的数组排序:
Arrays.parallelSort(numbers);
2. 根据指定的条件(比如是不是素数)对集合进行分组——
Map<Boolean, List<Integer>> groupByPrimary = numbers
.parallelStream().collect(Collectors.groupingBy(s -> Utility.isPrime(s)));
3. 过滤出你想要的值:
Integer[] prims = numbers.parallelStream().filter(s -> Utility.isPrime(s))
.toArray();
看看这个,再想想如果你自己用多线程来实现的话。开发效率瞬间提高了有木有!这个新结构我个人比较喜欢的人一点是它的分割迭代器(Spliterator)的概念,它将一个目标集合分隔成不同的块,这些块可以并行的进行处理,然后再合并到一起。跟它的前辈迭代器那样,它可以遍历一个集合,同时这个架构非常灵活,你可以自定义遍历以及分隔集合的操作,并直接传入方法即可。
它的性能表现如何?
我通过两个场景来进行并行操作的性能测试——低竞争以及高竞争的情况。原因在于如果你直接运行某个多核运算的算法的话,结果通常都会非常不错。但如果在一个真实的环境中运行的话,问题就出现了。真实环境下有大量的线程在不停的争夺宝贵的CPU资源进行消息或者用户请求的处理。这就是性能变差的原因。为了测试这种情况我进行了如下的测试。随机生成长度为10万的整型数组,取值在0到100万之间。然后分别使用传统的方式和并行的方式进行排序,分组以及过滤操作。结果在我们的预料之中。
1. 快排的性能快了4.7倍。
2. 分组的性能快了5倍左右。
3. 过滤的性能快了5.5.倍。
结果还算满意?当然不是。
我后来又做了一个额外的测试,将上述程序重复执行了100次,结果也是一样的。测试的机器是 i7处理器的MacBook Pro。
高负载下的情况如何?
目前为止结果还算不错,这是由于CPU资源的竞争并不激烈。这是理想情况下的结果,不过不幸的是,现实环境中可没有这么理想。为了模拟现实环境中的场景我写了第二个测试用例。这个测试运行的是同样的程序,不同的是这次有10个线程在并发的执行,来模拟并行处理10个请求的情况 。每个请求都通过传统的串行方式以及新的并行的方式来进行处理。
结果
排序快了20% —— 性能降低了23倍
过滤快了20% ——性能降低了25倍
分组慢了15%。
竞争冲突更严重的情况下性能差距肯定还会继续加大。原因在于,在多线程环境下,增加线程来进行处理其实是于事无补的。只有当CPU越多的情况下性能才会越好——线程多则无剂于事。
结论
尽管这些接口非常强大并且易于使用,但它们可不是什么“银子弹”。我们还得看具体情况来决定是否使用它们。如果你事先知道要并行的处理多个请求的话,最好考虑使用一个队列来保证并行处理的线程和你实际的CPU数一致。难点在于运行时的性能实际取决于硬件的体系结构以及压力程度的大小。你的程序可能只见识过压测的环境就直接上线运行了,这很容易出现写起来容易,调试起来费劲的问题。
原创文章转载请注明出处:
http://it.deepinmind.com
英文原文链接
分享到:
相关推荐
Java8并行流中自定义线程池操作示例主要介绍了Java8并行流中自定义线程池操作,结合实例形式分析了并行流的相关概念、定义及自定义线程池的相关操作技巧。 1. 概览 Java8引入了流的概念,流是作为一种对数据执行...
在Java 8中,`Stream` API 的并行化处理是通过`parallel()`方法实现的,它能够将一个流转换为并行流,从而使得流中的操作可以并行执行。在数列求和问题中,我们可以通过`IntStream.rangeClosed(1, 40000000000L)`...
文章首先介绍了基于Web的Java并行计算的基本概念及其背景,随后详细分析了利用Java进行Web上并行计算的可行性和潜在优势,并列举了一些具体的实现案例。最后,文中还提到了一个名为JET(Java Environment for Tasks...
### 并行操作技术介绍 ...综上所述,并行操作技术在提高程序性能方面具有显著优势,但在具体应用时也需要根据实际情况综合考虑各种因素。合理地选择串行或并行操作方式,可以使程序更加高效稳定。
在Java编程中,提高应用程序的性能是至关重要的。在给定的资料中,主要讨论了如何利用Java...在实际开发中,应结合CPU使用率、I/O延迟和系统吞吐量等指标,使用性能分析工具进行全面监控和调试,以达到最佳的性能效果。
并行编程在高性能计算领域的应用越来越广泛。国家863计划项目“网格服务环境结点建设及其支撑技术研究”的子课题 “用户开发环境研究”,旨在开发出以客户端/服务器模式运行的,能在远程编辑、编译、运行、调试并行...
在实际开发中,我们还会用到各种工具来辅助并行计算框架的调试和性能分析。例如,JVisualVM(或JProfiler等商业工具)可以监控线程状态、内存使用和CPU消耗,帮助我们找出潜在的性能瓶颈。此外,日志和性能计数器也...
### Java线程与并行详解 #### 一、Java线程基础 在Java中,**线程**是一种轻量级的进程,它允许一个程序同时执行多个任务,从而提高程序的执行效率。Java从1.0版本开始就支持多线程编程,并在后续版本中不断完善。...
快速排序(Quicksort)是一种非常高效的排序算法,在单线程环境下已经表现出色,而通过并行化处理,可以进一步提高其性能。本文将详细解析一个基于Java实现的并行快速排序示例代码。 #### 二、并行快速排序原理 ...
2. **识别瓶颈**:利用性能分析工具(如JProfiler、VisualVM等)找出程序中最耗时的部分。 3. **选择优化策略**:根据瓶颈的具体情况选择合适的优化策略,比如改进算法、减少内存分配、使用更高效的集合类等。 4...
- **BCI (Bytecode Instrumentation)**、**JVMTi (Java Virtual Machine Tool Interface)**、**javax.management** 和 **System.currentTimeMillis()**:这些技术为性能分析和动态代码修改提供了可能。 Java企业...
Java性能优化是一个持续且复杂的过程,它要求开发者不仅要具备扎实的编程基础和系统知识,还要能够使用各种性能分析工具。即便书中某些优化技术可能因Java版本更新而过时,但其中所传达的性能优化思想和分析方法仍然...
这篇博客“java自带压缩方式的性能比较”可能详细分析了这两种压缩方法的效率和应用场景。通过提供的代码文件`CompressTestMain.java`、`GzipUtils.java`和`ZipUtils.java`,我们可以推测作者可能构建了一个测试环境...
- **并行(parallel)数组操作**:Java 8的`Arrays`类和`Collections`类增加了并行操作,如并行排序。 - **并发(Concurrency)更新**:对并发框架进行了优化,如`ForkJoinPool`的改进和`CompletableFuture`的引入...
8. **Parallel Streams**:并行流是Stream API的一部分,它允许在多核处理器上并行执行流操作,从而提高计算性能。 9. **Nashorn JavaScript引擎**:Java8引入了Nashorn JavaScript引擎,允许Java代码直接执行...
Java Stream API 是 Java 8 引入的强大工具,提供了一种高效、简洁的方式来处理集合和数组数据。通过支持中间操作(如 filter()、map())和终结操作(如 forEach()、collect()),开发者可以以声明性方式进行数据...
11. **监控与诊断**:使用工具如VisualVM、JProfiler等进行性能分析,找出瓶颈。定期检查系统资源使用情况,如CPU、内存、磁盘I/O,以便及时发现并解决问题。 12. **代码审查**:团队间的代码审查可以帮助找出潜在...
另外,合理使用访问修饰符、避免过多的反射操作和动态类型,以及在适当的地方使用final关键字,都能对性能产生积极影响。 其次,JVM(Java虚拟机)的参数调优也是提升性能的关键。例如,通过调整-Xms和-Xmx设置堆...