C# 在插入ConcurrentDictionary时使用惰性计算是否会阻止多次计算请求的值?
Riccardo Terrell在其著作《.NET中的并发》(Concurrency In.NET)中提供了两个版本的Memoize函数(见下文),并声称第二个函数的性能优于第一个函数,因为它避免了重复的缓存项初始化,同时也是线程安全的 我的问题是-第二个版本是否仍然会导致重复的缓存项初始化 对于添加到字典中的每个键/值对,都会初始化并返回一个新的惰性实例,这意味着X个线程可能会导致X个惰性类型被初始化,最终导致X个func(a)调用,这正是函数的第一个版本中发生的情况?从我看到的情况来看,第二版的行为与第一版完全相同 第1版C# 在插入ConcurrentDictionary时使用惰性计算是否会阻止多次计算请求的值?,c#,.net,C#,.net,Riccardo Terrell在其著作《.NET中的并发》(Concurrency In.NET)中提供了两个版本的Memoize函数(见下文),并声称第二个函数的性能优于第一个函数,因为它避免了重复的缓存项初始化,同时也是线程安全的 我的问题是-第二个版本是否仍然会导致重复的缓存项初始化 对于添加到字典中的每个键/值对,都会初始化并返回一个新的惰性实例,这意味着X个线程可能会导致X个惰性类型被初始化,最终导致X个func(a)调用,这正是函数的第一个版本中发生的情况?从我看到的情况来看,第二
public Func<T, R> MemoizeThreadSafe<T, R>(Func<T, R> func) where T : IComparable
{
ConcurrentDictionary<T, R> cache = new ConcurrentDictionary<T, R>(); ①
return arg => cache.GetOrAdd(arg, a => func(a));
}
public Func MemoizeThreadSafe(Func Func)其中T:i可比较
{
ConcurrentDictionary缓存=新建ConcurrentDictionary();①
返回arg=>cache.GetOrAdd(arg,a=>func(a));
}
第2版
static Func<T, R> MemoizeLazyThreadSafe<T, R>(Func<T, R> func) where T : IComparable
{
ConcurrentDictionary<T, Lazy<R>> cache = new ConcurrentDictionary<T, Lazy<R>>(); ①
return arg => cache.GetOrAdd(arg, a => new Lazy<R>(() => func(a))).Value;
}
static Func MemoizeLazyThreadSafe(Func Func)其中T:i可比较
{
ConcurrentDictionary缓存=新建ConcurrentDictionary();①
返回arg=>cache.GetOrAdd(arg,a=>newlazy(()=>func(a))).Value;
}
GetOrAdd
将始终返回相同的值。两个线程可能会竞相为同一个参数值创建一个惰性
,但它们最终都只会引用其中一个。它们都会依次调用它的Value
,它会自己初始化一次。只有对Value
的调用才强制执行此初始化,并且只有在该调用之后才会调用func(a)
另一个Lazy
将被放弃,并最终成为GCed1,而无需初始化其值
1假设GC将来会运行,那么您就不会使用空GC等运行。
GetOrAdd
将始终返回相同的值。两个线程可能会竞相为同一个参数值创建一个惰性
,但它们最终都只会引用其中一个。它们都会依次调用它的Value
,它会自己初始化一次。只有对Value
的调用才强制执行此初始化,并且只有在该调用之后才会调用func(a)
另一个Lazy
将被放弃,并最终成为GCed1,而无需初始化其值
1假设GC将来会运行,那么您不会使用空GC运行。太好了,谢谢。我没有想到会创建两个
Lazy
,但只会访问其中一个的值,因此不会初始化另一个中包含的值。太好了,谢谢。我没有想到会同时创建Lazy
,但只会访问其中一个的值,因此不会初始化另一个中包含的值。