Scala性能比较之集合

Posted Nathon的学习笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala性能比较之集合相关的知识,希望对你有一定的参考价值。

在scala里面使用集合做处理的时候,通常会考虑Map,List和Seq,这些常用的不可变集合大多数情况下可以解决很多问题。但是,当我们集合操作变得复杂时候,就需要考虑性能问题。

首先,可以来看看Map集合,继承方面跟java有些类似:

Scala性能比较之集合

Hashmap跟Hashset,Treemap跟Treeset的数据结构类似,在scala里面通常我们使用Hashmap较多。从数据结构上,Hashset是一种树状结构并且每个节点有32个子树,每个节点存储了相应的hashcode。可以通过一个例子来看:

这里我定义了一个hashset,但是可以看到结果却是无序的。为什么?原因也就是上面提到的,hashset集合里面的元素是根据hashcode得到的。其核心代码如下,也就说对元素做了异或,移位等操作。换言之,也就是在查找集合中的元素时候,将元素先转换成二进制,从右往左依次每个5位二进程码在对应的树上查询是否有对应的二进制码对应,直到找到需要的元素。从性能角度来讲,Hashset的搜索时间复杂度为Log32N,因为它的每一个节点都有32个分支,这一点与Treeset不一样,Treeset的结果是二叉树,时间复杂度为Log2N。所以,比如有100万的数据量,采用Hashset最多只需4层节点搞定,而采用Treeset需要近20层。

因此,通常数据量很小情况下,使用set基本可以处理;当元素量巨大的时候,优先选择Hashset;那么什么情况下使用Treeset较好?Hashset也会有缺点,比如产生哈希碰撞,当这种情况出现较多时候,可以采取Treeset规避。

同理,这些逻辑也对应于Hashmap和Treemap。

最后,来看看Seq,vector和list继承自Seq.

vector的特点与hashset很类似,只不过是通过下标来标识集合中的元素,因为下标不会重复,所以不会出现哈希碰撞的情形,这样性能比Hashset要好,虽然时间复杂度都是Log32N。

List的结构是单链表形式,基于这种数据结构,所以它适合于频繁的对集合中的头部与尾元素部进行操作的场景。


以上是关于Scala性能比较之集合的主要内容,如果未能解决你的问题,请参考以下文章

电子书丨《Scala集合技术手册》

Scala的map实现key和value排序及各种排序比较等知识讨论

用队列来处理订单以及集合间性能比较

JUC并发编程 共享模式之工具 JUC 线程安全的集合类 -- 线程安全的集合类概述

SetListHashMap优缺点比较,高性能集合

Android应用性能优化之使用SparseArray替代HashMap