Java中访问大容量数组是否会导致访问速度变慢?
性能差异核心原因
你观察到的不同大小数组随机访问耗时差异,主要来自三类硬件层面的访问命中率差异,哪怕数组总大小远大于CPU L3缓存,这些差异也会被千万级的访问量放大为可观测的耗时差:
- TLB(地址转换快表)命中率差异
主流x86架构默认内存页大小为4KB,1亿容量的int数组总大小400MB,共对应10万个4KB内存页;3亿数组对应30万个页,10亿数组对应100万个页。而CPU的L2 TLB通常只有几千项的容量,专门用于缓存虚拟地址到物理地址的转换结果。数组总页数越少,随机访问时命中TLB的概率就越高,不需要走耗时极高的多级页表查询,整体访问速度就越快。 - CPU缓存行的偶发命中收益
CPU缓存的最小管理单元是64字节的缓存行,对应16个连续的int元素。哪怕你的访问是完全随机的,数组规模越小,多次随机访问落到同一个缓存行的概率就越高。这种偶发的缓存命中看似概率不高,但乘以千万级的访问基数后,累计节省的耗时会非常明显。 - DRAM行开放命中率差异
内存DRAM的最小读写单元是2KB/4KB的行,内存控制器打开某一行后,后续访问同个行的地址延迟会比打开新行低70%以上。数组规模越小,所有元素占的DRAM总行数越少,随机访问命中已开放DRAM行的概率越高,也会带来显著的性能提升。
补充说明:你之前认为数组大小对随机访问速度没有影响的结论,仅在数组规模差异足够大、所有命中率都趋近于0的极限场景下才成立,你的测试场景还未达到这个阈值。
内容的提问来源于stack exchange,提问作者Will Kanga
相关产品推荐
相关产品推荐

