当操作为0(1)时,是否值得缓存.count(或.count())的结果?

本文关键字:count 缓存 值得 结果 操作 是否 | 更新日期: 2023-09-27 18:03:17

如果.Count或.Count()在实现iccollection的对象上多次使用(因此计算复杂度为0(1),当然除非它已被覆盖),那么在性能方面(而不是内存方面),即使是非常小的差异,将值缓存在临时变量中而不是每次需要时访问属性值是否更好?

当操作为0(1)时,是否值得缓存.count(或.count())的结果?

是的,它可以(稍微)快一些,因为方法调用的开销、相关的错误检查以及(在Count()的情况下)iccollection的动态类型检查都有一定的开销。

值得吗?这完全取决于您和您的应用程序。如果你处在一个非常紧密的内部循环中,这可能是值得的。然后,在最近的。net运行时中,这种琐碎的属性可能会在这种情况下被内联。

与往常一样,让您的分析器告诉您应用程序中的热点在哪里。

直接回答问题,即使是一个0(1)的操作也需要很长时间才能完成;只是不管收藏有多大,它花的时间总是一样的。缓存结果并读取它总是很快,但不能保证比任何给定的O(1)操作都快。你需要先计时;)

对不起,认为ICollection.CountO(1)是错误的。道德上应该是这样的,但不能保证是这样的:

public EvilCollection<T> : ICollection<T> {
    private readonly ICollection<T> collection;
    private readonly Func<int, int> slowGrowingFunction;
    public EvilCollection(
        ICollection<T> collection,
        Func<int, int> slowGrowingFunction) 
    {
        this.collection = collection;
        this.slowGrowingFunction = slowGrowingFunction;
    }
    public int Count {
        get {
            Thread.Sleep(1000 * this.slowGrowingFunction(this.collection.Count));
            return this.collection.Count;
        }
    }
    // other methods wrap methods on collection for ICollection<T>
}
ICollection<T> evilCollection = 
    new EvilCollection<T>(collection, n => Ackermann(4, n));

哦不,evilCollection.CountO(Ackermann(4, n)) !

也就是说,我不会担心这个,除非我知道我可能会进入邪恶的集合,并且我发现它是一个重要的性能瓶颈。请记住,代码不太清楚,它可能不太正确(缓存结果后计数更新是多少?),等等。

只需编写最简单的代码即可(使用ICollection<T>.Count)。当且仅当它是应用程序的性能瓶颈时,我才会担心调优它。

不,没有必要;使用临时变量没有任何好处。此外,如果缓存计数,则在集合集发生更改时,可能会有计数不正确的风险。

答案是NO如果你确定.Count()将在现在和功能中做什么。如果.Count()是一些可能改变的实现,答案是YES。假设你改变了一些LinkedList的实现,它可能不是O(1)。