管理带有移动项目的列表的(几乎)最佳方式

Mix*_*oid 9 c# performance list

情况就是这样:
我列出了哪些字符串实际上是数字并且可以变得非常大(数亿项).
我将数字存储为字符串,因为有一个选项可以显示一些附加信息,即文本.

因为这需要大量的内存来存储我决定我最多只能存储500万个项目.(这只需要250-300mb).

该列表由计算输出填充.如果找到一个数字,它将被添加到列表中,此数字始终大于现有项目.

当列表达到5密耳时,我想删除第一个项目并将新项目添加到列表中.

喜欢:

    // Why is this so freaking slow???
    if (_result.Count == 5000000)
        _result.RemoveAt(0);
    _result.Add(result);
Run Code Online (Sandbox Code Playgroud)

正如你在评论中看到的那样,这非常非常非常慢.它只是将我的表现减少了15倍.花了2分钟,现在需要大约30分钟.

我用linq尝试过一些东西,.Skip(1).ToList但是会重新创建列表,因此更慢.

列表必须保持正确的顺序,因此不能通过索引覆盖(除非您可以解释一个很好的解决方法).

我的问题:
有没有合适的方法来做到这一点?

我真的需要这里的表现,因为它可能需要检查大约10000000000个数字.这可能需要一天的时间,但一个月有点太多了:(.

需要更多信息,随时问,我很乐意提供.

解决方案:
执行O(1)

    // Set the _result
    Queue<object> _result = new Queue<object>(5000000);

    /// Inside the method
    // If the count has reach it's max, dequeue the first item
    if (_result.Count == 5000000)
        _result.Dequeue();
    _result.Enqueue(result);
Run Code Online (Sandbox Code Playgroud)

Guv*_*nte 4

您曾经重新订购过商品吗?如果不这样做,循环队列就可以很好地工作。

System.Collections.Generic.Queue 就是其中之一,我刚刚仔细检查过。

为了扩展队列的好处,这是RemoveAt实现(大致):

for (int i = 1; i < count; i++)
    items[i-1] = items[i];
count--;
Run Code Online (Sandbox Code Playgroud)

因为list[0]始终是第一项,所以您必须移动所有内容才能删除第一项。

相反,队列单独跟踪第一个项目。这将上面的代码更改为:

head++
Run Code Online (Sandbox Code Playgroud)