遍历JDBC ResultSet累计数据时选ArrayList还是LinkedList性能更优?
结论
不需要将ArrayList替换为LinkedList,当前使用ArrayList的方案性能已经是最优的,替换为LinkedList反而会导致性能下降。
具体原因
- 适用场景匹配:LinkedList的性能优势仅体现在列表中间位置的随机插入/删除场景,你的场景只有尾插新增数据、后续全量遍历序列化两个操作,完全用不到LinkedList的特性。
- 尾插性能对比:ArrayList的尾插分摊时间复杂度为O(1),默认1.5倍的扩容机制下,数千条数据的场景只会触发个位数次数的扩容,扩容时的数组批量复制开销极低。而LinkedList每次插入都需要创建新的节点对象、修改前后节点的指针引用,内存开销和操作耗时都高于ArrayList的尾插操作。
- 遍历性能对比:后续服务层做XML/JSON序列化时需要全量遍历列表,ArrayList底层是连续存储的数组,内存连续性好,CPU缓存命中率极高,遍历速度远优于LinkedList。LinkedList的节点分散在堆内存中,遍历时会频繁触发CPU缓存失效,相同数据量下遍历速度比ArrayList慢30%~50%。
可选优化方案
如果想要进一步提升性能,可以在初始化ArrayList时指定和预期数据量匹配的初始容量,完全规避扩容开销,示例代码如下:
// 已知查询结果量级约为2000条时,直接指定初始容量 List<Company> list = new ArrayList<>(2000); ResultSet rs = statement.execute(); while (rs.next()){ Company company = new Company(); company.setCompanyName(rs.getString("company_name")); company.setCompanyId(rs.getInteger("company_id")); list.add(company); }
如果无法预估准确数据量,也可以通过JDBC结果集的getFetchSize()方法拿到驱动预取的行数作为初始容量参考。
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

