这是你想要的吗?
static ILookup<TKey, TValue> Copy<TKey, TValue>(ILookup<TKey, TValue> lookup)
{
return lookup.
SelectMany(g => g,
(g, v) => new KeyValuePair<TKey, TValue>(g.Key, v)).
ToLookup(kvp => kvp.Key, kvp => kvp.Value);
}
当然,如果你想以某种方式转换这些值,也许你想要这样的东西:
static ILookup<TKey, TValueOut> Transform<TKey, TValue, TValueOut>(
ILookup<TKey, TValue> lookup,
Func<TValue, TValueOut> selector)
{
return lookup.
SelectMany(g => g,
(g, v) => new KeyValuePair<TKey, TValueOut>(g.Key, selector(v))).
ToLookup(kvp => kvp.Key, kvp => kvp.Value);
}
KeyValuePair
它是一种值类型,存储在堆栈上,因此不需要任何中间内存分配。我分析了一个创建
Lookup<int,int>
有100个密钥,每个密钥有10000个项目(总共1000000个)。
-
Lookup
执行1610个分配。
-
用我的方法复制它可以进行1712次分配(创建它所需的所有分配,以及
SelectMany
为每个键调用一个枚举器)。
-
用匿名对象复制而不是
执行1001712分配(复制所需的所有分配加上每个项目的一个分配)。
CPU方面,即使在
查找
两种复制方法的性能相同。每个键有1000000个元素,这两种方法的性能不同:
-
5.1秒创建
-
键值对
-
使用匿名对象复制的时间为6.3秒