IEnumerable.First 和 IEnumerable.Last 的效率如何?

How efficient is IEnumerable.First and IEnumerable.Last?

我想使用 System.Collections.Generic.Queue,但有一个区别:我希望 Queue.Peek 到 return 最后一项而不是第一项。我仍然希望项目以相同的方式进入和退出。

我正在考虑使用 Queue.Last() 作为 Queue.Peek() 的替代方案(我认为它与 Queue.First() 基本相同)但我想知道如果这意味着枚举器将在到达最后一个元素之前遍历整个队列。由于我的队列会非常大,这可能是个问题。

编辑:

为了正确看待我正在尝试做的事情:假设我想保留过去 20 年股票价格的每分钟数据库。这将是许多数据点。为了做到这一点,我想在每分钟排队最新的价格,并在队列大小超过 20 年时出队最早的价格。但是,我还想要一种方便的方法来从队列中获取最新价格。我知道 Queue.Last(),它可以解决问题,但我只是想知道它是否会非常低效。

如果集合实现 IList<T>,则 the indexer property is usedFirst()Last() 中(即 通常 O(1),尽管这不是必需的)。

否则,对First()的调用将只获取第一个元素(并立即退出,如果枚举器支持延迟执行),但调用 Last() 将必须枚举整个集合 .

IQueue<T> 没有实现 IList<T>.

听起来你不想使用队列而是使用双端队列。

执行 Last 调用将创建一个 Enumerator 实例,Queue<T> 的私有内部 class 将用于从头到尾枚举,因为 Queue<T> 没有实现 IList<T> 接口。因此 Last 将是一个 O(n) 操作。

你是对的 - 对于队列,Last 将遍历每个元素。 Enumerable.Last 有 IList 的快捷方式,但没有队列的快捷方式。

听起来您只想要一个能够记住最后添加的项目的队列。您可以围绕 Queue 创建一个简单的包装器,它可以有效地 return 最后一项...

public class StockQueue<T>
{
    private readonly queue; 

    public StockQueue(Queue<T> source)
    {
        this.queue = source;
    }

    public T LastAdded {get; private set;}

    public Enqueue(T item)
    {
        // Remember the last item added
        this.lastAdded = item;
        this.queue.Enqueue(item);
    }

    // Implement any other Queue members you need, passing the calls through
    // to the internal queue.
    public T Dequeue()
    {
        return this.queue.Dequeue();
    }

    public T Peek()
    {
        return this.queue.Peek();
    }
}