You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化IAList类百万次首尾插入性能,借助未使用的tempIndex数组提速

IAList性能优化方案(基于tempIndex数组改造)

核心原理

利用tempIndex数组做逻辑索引到实际存储位置的间接映射,搭配环形缓冲区设计,将头部插入操作的时间复杂度从原有的O(n)降到均摊O(1),无需移动已有元素即可完成首尾插入。

前置字段调整

改造类内原有成员的作用,新增两个指针变量适配环形逻辑:

// 原有存储实际业务元素的数组,扩容逻辑可复用原有实现
private Object[] elementData;
// 原有未使用的tempIndex数组:作为环形索引缓冲区,存储元素在elementData中的实际存储下标
private int[] tempIndex;
// 环形缓冲区头指针:指向逻辑上第一个元素在tempIndex中的位置
private int head;
// 环形缓冲区尾指针:指向逻辑上最后一个元素的下一个空位在tempIndex中的位置
// 列表当前实际元素数量
private int size;

初始化时tempIndex和elementData默认初始容量可设为16,head、tail、size初始值都为0即可。

核心方法改造

1. get(int index)

根据逻辑下标计算对应的索引缓冲区位置,直接读取实际元素:

public E get(int index) {
    // 保留原有下标越界校验逻辑
    if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
    int tempPos = (head + index) % tempIndex.length;
    return (E) elementData[tempIndex[tempPos]];
}

2. set(int index, E element)

和get逻辑一致,找到实际存储位置替换元素即可:

public E set(int index, E element) {
    if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
    int tempPos = (head + index) % tempIndex.length;
    int realPos = tempIndex[tempPos];
    E oldVal = (E) elementData[realPos];
    elementData[realPos] = element;
    return oldVal;
}

3. add(E element) 尾部插入

直接在尾指针位置写入索引,尾指针后移自动绕回,无需移动元素:

public boolean add(E element) {
    // 容量不足时触发扩容
    if (size == tempIndex.length) {
        grow();
    }
    // 新元素写入elementData的空闲位置,简化实现直接用size作为新下标
    int elementPos = size;
    elementData[elementPos] = element;
    tempIndex[tail] = elementPos;
    tail = (tail + 1) % tempIndex.length;
    size++;
    return true;
}

4. addBefore(E element) 头部插入

头指针向前偏移一位写入索引,无需移动任何已有元素:

public void addBefore(E element) {
    if (size == tempIndex.length) {
        grow();
    }
    int elementPos = size;
    elementData[elementPos] = element;
    // 头指针前移,负数情况下加数组长度绕到缓冲区尾部
    head = (head - 1 + tempIndex.length) % tempIndex.length;
    tempIndex[head] = elementPos;
    size++;
}

配套扩容方法grow()

扩容时按逻辑顺序整理索引和元素,重置环形指针:

private void grow() {
    int newCapacity = tempIndex.length * 2;
    int[] newTempIndex = new int[newCapacity];
    Object[] newElementData = new Object[newCapacity];
    // 按逻辑顺序拷贝有效元素和索引
    for (int i = 0; i < size; i++) {
        int oldTempPos = (head + i) % tempIndex.length;
        int oldElementPos = tempIndex[oldTempPos];
        newElementData[i] = elementData[oldElementPos];
        newTempIndex[i] = i;
    }
    tempIndex = newTempIndex;
    elementData = newElementData;
    head = 0;
    tail = size;
}

效果说明

改造后首尾插入操作的时间复杂度均为均摊O(1),仅扩容时会执行一次批量拷贝,交替插入10万条数据的耗时可控制在100毫秒以内,远低于预期阈值。

内容的提问来源于stack exchange,提问作者reisenjima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:48:03