gpt4 book ai didi

c# - GetOrAdd 新的与出厂性能

转载 作者:行者123 更新时间:2023-11-30 20:32:16 24 4
gpt4 key购买 nike

下面哪两段代码在不同情况下表现更好,为什么?

1

private readonly ConcurrentDictionary<int, List<T>> _coll;
_coll.GetOrAdd(1, new List<T>());

这会在每次调用时创建一个新的 List,即使在不需要它时也是如此(如果我们将 capacity 传递为 0,此语句还有多大意义?)。

2

private readonly ConcurrentDictionary<int, List<T>> _coll;
_coll.GetOrAdd(1, (val) => new List<T>());

这只会根据需要创建 List,但有一个委托(delegate)调用。

最佳答案

在内存方面,第一种方法每次都会导致分配,而第二种方法将使用缓存的委托(delegate)对象,因为它不捕获任何变量。编译器处理缓存委托(delegate)的生成。自 List<T> 的默认构造函数以来,容量设置为零的第一种情况没有区别。在初始化时使用空数组,与显式容量 0 相同。

在执行指令方面,由于没有使用第二个参数,因此在找到 key 时它们是相同的。如果找不到 key ,第一种方法只需读取局部变量,而第二种方法将有一个间接层来调用委托(delegate)。另外,looking into the source code ,似乎 GetOrAdd 与工厂将进行额外的查找(通过 TryGetValue)以避免调用工厂。委托(delegate)也可能被执行多次。 GetOrAdd 只是保证您在字典中看到一个条目,而不是只调用一次工厂。

总而言之,如果通常找不到 key ,第一种方法可能会更高效,因为无论如何都需要进行分配,并且没有通过委托(delegate)进行间接访问。但是,如果通常找到 key ,则第二种方法性能更高,因为分配更少。对于缓存中的实现,您通常希望有很多命中,所以如果是这样的话,我会推荐第二种方法。实际上,两者之间的差异取决于整个应用程序对此代码路径中的分配有多敏感。

此外,无论使用它的实现是什么,都可能需要围绕 List<T> 实现锁定。这是返回的,因为它不是线程安全的。

关于c# - GetOrAdd 新的与出厂性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41784863/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com