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

自定义图表控件:高效保留最新1024个double值的实现咨询

现有两种实现的问题

  • List方式:Insert(0, newValue)会触发List内部数组的所有元素向后移动一位,每次操作时间复杂度为O(n)(n=1024),频繁调用时性能开销显著。虽然初始化了足够容量避免扩容,但元素移动的核心开销无法消除。
  • 普通数组方式:Array.Copy需要复制1023个元素到新位置,时间复杂度同样是O(n),和List方式本质一致,没有解决元素移动的性能问题。

推荐方案:环形缓冲区(Circular Buffer)

环形缓冲区通过维护一个指针记录插入位置,实现O(1)时间复杂度的元素添加,完全避免元素移动,内存占用固定无额外分配,是这类场景的最优解。

实现思路

  1. 初始化固定大小的数组(长度1024)
  2. 用变量记录下一个插入元素的索引
  3. 添加新元素时直接写入对应索引位置,通过取模运算让指针循环回到数组开头
  4. 读取元素时,根据指针位置计算实际索引,确保返回最新元素在前的有序序列

代码示例

private readonly double[] _buffer = new double[1024];
private int _nextInsertIndex = 0;
private int _elementCount = 0;

public void AddValue(double newValue)
{
    _buffer[_nextInsertIndex] = newValue;
    _nextInsertIndex = (_nextInsertIndex + 1) % _buffer.Length;
    if (_elementCount < _buffer.Length)
    {
        _elementCount++;
    }
}

// 获取供绘制的有序元素(最新元素在前)
public IEnumerable<double> GetOrderedValues()
{
    for (int i = 0; i < _elementCount; i++)
    {
        // 从下一个插入位置的前一位开始倒序计算索引
        int targetIndex = (_nextInsertIndex - 1 - i + _buffer.Length) % _buffer.Length;
        yield return _buffer[targetIndex];
    }
}

额外优化

如果你的绘制逻辑支持直接遍历环形缓冲区的原始顺序(无需先整理成最新在前的序列),可以跳过GetOrderedValues方法,直接按指针位置反向遍历数组,进一步降低性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:03:14