【发布时间】:2016-08-16 22:06:37
【问题描述】:
假设我正在以每秒 50 到 200 次的可变速率接收信号。我想将收到的每个信号的时间戳存储到队列中,以便在超过 1 周前收到信号时将其从队列中删除。
public Queue<long> myQueue = new Queue<long>();
public OnSignalReceived()
{
myQueue.Enqueue(DateTime.UtcNow.Ticks);
PurgeOldSignals();
}
public void PurgeOldSignals()
{
while (myQueue.Count > 0 && myQueue.Peek() < DateTime.UtcNow.AddDays(-7).Ticks)
{
myQueue.Dequeue();
}
}
有没有更有效的方法来做到这一点?这是我的实现,我希望利用大量内存(因为假设平均每秒 100 个信号,这意味着队列将在开始清除项目之前保存大约 6000 万个项目(!))作为交换由于 Enqueue() 和 Dequeue() 的 O(1) 时间而具有计算性能。
然而,经过测试,我注意到瓶颈是 CPU 而不是 RAM。事实上,RAM 几乎没有被吃光,但 CPU 使用率从未停止增加。这是运行大约 16 小时后的结果(显然与我的 7 天目标相去甚远)
有什么优化的建议吗?
编辑 1:
事实上,这样做的全部目的只是随时了解我在上周收到了多少信号(精确到实际秒数)。也许有更好的方法来实现这一点?
【问题讨论】:
-
一目了然,你说每秒会有100个信号(每10毫秒一个)。计算机应该以纳秒级的速度处理内存配置,因此从队列中取出 100 个信号只需要 100 纳秒(甚至不到一微秒)。这意味着处理器正在以极快的速度处理 while 循环,因此内存受到限制,无法疯狂增长。
-
最简单的做法可能是限制清理。让它每秒只触发一次或类似的效果。
-
也许
ConcurrentQueue<T>更适合读写器线程? -
为什么要在内存中保存 7 天 的数据(无论是几百万)在开始处理之前??跨度>
-
如果您创建的队列的初始容量是预期的最大容量,会发生什么情况?事实上,你会做很多成长,这会变得越来越昂贵。
标签: c# performance data-structures