高性能的Java集合迭代

了解有关Java中forEach循环的更多信息,以及本文中有关使用Java处理集合的C style和Stream API的比较。

介绍

Java开发人员通常处理诸如ArrayList和HashSet之类的集合。Java 8附带了lambda和流Stream API,可以帮助我们轻松处理集合。在大多数情况下,我们使用几千个项目并且性能不是问题。但是,在某些极端情况下,当我们不得不多次遍历几百万个item时,性能将变得很痛苦。

我使用JMH来检查每个代码片段的运行时间。

forEach vs. C Style vs. Stream API

迭代是一个基本功能。所有编程语言都有简单的语法,允许程序员运行集合。Stream API可以非常直接的方式迭代集合。

高性能的Java集合迭代

forEach循环同样简单:

高性能的Java集合迭代

C style更冗长,但仍然非常紧凑:

高性能的Java集合迭代

性能表现:

高性能的Java集合迭代

使用C style,JVM只会增加一个整数,然后直接从内存中读取值。这使它非常快。但是,根据StackOverFlow社区上的这个答案和来自Oracle的文档,每个都是非常不同的,JVM必须将forEach转换为迭代器并对每个项目调用hasNext()。这就是为什么forEach比C style慢。

哪种是高性能的遍历方式?

我们定义测试数据:

高性能的Java集合迭代

Java Set还支持Stream API和forEach循环。根据之前的测试,如果我们将Set转换为ArrayList,然后通过ArrayList,可能性能提升?

高性能的Java集合迭代

迭代器与C style for循环的组合怎么样?

高性能的Java集合迭代

或者,简单的遍历呢?

高性能的Java集合迭代

这是一个不错的主意,但它不起作用,因为初始化新的ArrayList也会消耗资源。

高性能的Java集合迭代

HashMap(HashSet使用HashMap )不是为迭代所有项而设计的。迭代HashMap的最快方法是Iterator和C style for循环的组合,因为JVM不必调用hasNext()。

结论

使用Foreach和Stream API可以方便地使用集合。你可以更快地编写代码。但是,当你的系统稳定并且性能是一个主要问题时,你应该考虑重写你的循环。


分享到:


相關文章: