fastutil
介绍
fastutil
扩展了 Java™ 集合框架,
提供 类型特定的 Map、Set、List 和 Queue,具备 内存占用小、访问和插入速度快 的特点;
同时它还提供了 大容量(64 位)数组、集合和列表,以及用于二进制和文本文件的快速、实用 I/O 类。
这是一个自由软件,遵循 Apache License 2.0 许可证发布。
这些类实现了它们对应的标准接口(例如 Map 对应 Map
接口),可以无缝接入现有代码。
此外,它们还提供了额外功能(如双向迭代器),标准类中并不提供。
除了对象和基本类型,fastutil
类还支持 引用类型(references),
即使用 ==
判断相等而不是 equals()
方法。
源代码使用 C 预处理器生成,从一组驱动文件开始生成。
你可以查看 javadoc
生成的文档,其中概述部分解释了 fastutil
的设计选择。
核心 Jar
如果标准的 fastutil
Jar 文件太大,可以使用 核心 (core) Jar,
它只包含针对整数、长整数和双精度浮点数的数据结构。
注意,这些类在标准 Jar 中也有重复,如果项目同时依赖两者(例如由于传递依赖),
应排除核心 Jar,以避免冲突。
你也可以使用 find-deps.sh
脚本生成一个 小型定制 Jar(可以放在项目仓库或本地 Maven 仓库中)。
此脚本依赖很少,只需要 JDK 8 自带的 jdeps
工具即可。
它可以帮助你识别项目中实际使用的 fastutil 类,并生成只包含必要类的最小化 Jar。
构建
首先,你需要执行 make sources
来获取实际的 Java 源码。
之后执行 ant jar
会生成单个 Jar 文件;
ant javadoc
会生成 API 文档;
ant junit
会运行单元测试。
如果想要获取上面提到的两个 Jar,需要先运行脚本 split.sh
,然后执行 ant osgi-rest
。
Java 源码是通过 C 预处理器生成的。
gencsource.sh
脚本会读取驱动文件(包含预处理器定义的符号和条件编译),
生成一个(伪)C 源文件,该文件包含驱动代码和用于定制环境的定义。
性能
fastutil
在许多情况下提供了最快的实现。
你也可以找到许多其他原始类型集合的实现(如 HPPC、Koloboke 等)。
有时作者会称自己的实现为“最快可用”,但实际情况是任何实现都需要做一些折中决策, 这些决策会在不同场景下让性能快或慢。 因此建议 总是在自己的应用中测试速度,不要仅依赖通用基准测试,并向作者咨询如何最佳使用库。 尤其是测试基于哈希的数据结构时,应该显式设置 负载因子(load factor),因为速度高度依赖碰撞链长度。
大数据结构
在 fastutil 6
中,引入了一套新的类,可以处理 非常大的集合,
特别是 大小超过 2³¹ 的集合。
- 大数组(big arrays)是“数组的数组”,通过丰富的静态方法操作,就像是带有 64 位索引的一维数组。
- 大列表(big lists)提供 64 位列表访问。
- 哈希大集合(hash big set)的大小只受核心内存限制。