选择Native Array、Stack、ArrayList或List实现10点滑动平均低通滤波器
嘿,这个做滑动平均低通滤波器的需求我太熟了!咱们先逐个分析你纠结的几个容器,然后给你最适合的实现方案~
各容器适配性分析
1. .NET 原生数组(Native Array)
- 优点:内存连续,访问速度快
- 缺点:固定长度,需要手动管理元素移位(比如新元素进来要把所有元素往前挪一位),代码繁琐。虽然你的场景是固定10个元素能凑合用,但维护成本太高,不推荐。
2. Stack
- 完全不适合!Stack是后进先出的结构,而你需要移除最早加入的元素(先进先出场景),每次要实现这个逻辑得把整个Stack倒腾一遍,效率极低,直接排除。
3. ArrayList
- 老框架遗留产物,非泛型集合。因为你存的是float值类型,每次存取都要拆箱装箱,有性能损耗,而且类型不安全,现在.NET里早就不推荐用了,优先选泛型集合。
4. List
- 泛型类型安全,无拆箱装箱问题,API丰富(Add、RemoveAt这些操作都很方便)。唯一小缺点是频繁调用
RemoveAt(0)时,内部数组需要移位,有一点性能开销,但你的窗口只有10个元素,这个开销完全可以忽略,适合快速开发。
额外推荐:Queue
其实还有个更贴合你需求的容器——QueueEnqueue和Dequeue操作都是O(1)的,性能比List更优。
最优实现:基于Queue
这里我还额外维护了一个_totalSum变量,避免每次计算平均值都遍历整个队列,进一步提升性能:
public class MovingAverageFilter { private readonly Queue<float> _valueQueue = new Queue<float>(); private const int _windowSize = 10; private float _totalSum = 0f; public float Update(float newValue) { // 加入新值并累加总和 _valueQueue.Enqueue(newValue); _totalSum += newValue; // 超过窗口大小则移除最早元素,并从总和中扣除 if (_valueQueue.Count > _windowSize) { float oldestValue = _valueQueue.Dequeue(); _totalSum -= oldestValue; } // 返回平均值,初始化阶段元素不足10个时也能正确计算 return _totalSum / _valueQueue.Count; } }
备选实现:基于List
如果因为某些原因不想用Queue,List的实现会更简洁,只是性能略逊一筹(但10个元素完全感知不到):
public class MovingAverageFilter { private readonly List<float> _valueList = new List<float>(); private const int _windowSize = 10; public float Update(float newValue) { _valueList.Add(newValue); if (_valueList.Count > _windowSize) { _valueList.RemoveAt(0); } // 直接用LINQ的Average方法,代码更简洁 return _valueList.Average(); } }
总结
- 优先选Queue
:最贴合需求,性能最优,代码易维护 - 其次选List
:API丰富,代码简洁,适合快速开发 - 原生数组:代码繁琐,维护成本高,不推荐
- Stack和ArrayList:完全不匹配需求,直接排除
内容的提问来源于stack exchange,提问作者Bachalo
相关产品推荐
相关产品推荐

