正常化数组的ConcurrentDictionary
问题描述:
我有一个数组的ConcurrentDictionary,其中每个数组具有相同的固定大小。它看起来像这样:ConcurrentDictionary<int, double[]> ItemFeatures
正常化数组的ConcurrentDictionary
我想通过将所有值除以该列中值的最大值来标准化列表中的值。例如,如果我的列表大小为5,我希望第一个位置中的每个元素除以该位置中所有值的最大值,以此类推位置2。
我可以想到做到这一点的天真方式是,首先迭代列表中的每个列表和每个元素,并存储每个位置的最大值。然后再次遍历它们并将它们除以先前找到的最大值。
Linq中有没有更好的方法来做到这一点?这些字典会很大,所以效率越高/耗时越少越好。
答
不,这实际上是最有效的方法。最后,无论如何你都需要这样做,你不能跳过任何东西。你可以用LINQ编写它,但性能会更差,因为它会有很多函数调用和内存分配。 LINQ不会创造奇迹,它只是一种(有时)写作方式的更短的方式。
如果您的算法具有良好的“缓存局部性” - 换句话说,如果您以顺序方式访问计算机内存,什么才能加快速度。在.NET这样的环境中很难保证,但是像你描述的循环可能有接近它的最好机会。
答
LINQ旨在查询数据,而不是修改数据。您可以使用一个小LINQ来计算最大值,但也差不多了:
var cols = ItemFeatures.First().Value.Length;
var maxv = new double[cols];
for (var j1 = 0; j1 < cols; ++j1)
maxv[j1] = ItemFeatures.Values.Select(vs => vs[j1]).Max();
foreach (var kvp in ItemFeatures)
for (var j1 = 0; j1 < cols; ++j1)
kvp.Value[j1] /= maxv[j1];
LINQ不会使代码做任何少,充其量它只是阻止你需要编写大量的代码做同样的事情,你需要遍历所有的数据来找到每个位置的最大值;如果不查看每个值,就无法找到最大值,这根本就没有办法解决。 – Servy
当你这样做时,其他线程是否会访问'ConccurrentDictionary'?如果是这样,问题可能无法解决。 – Servy
@Servy显然Linq不能创造奇迹。我的问题是,这是否会以某种方式更有效(就内存分配或时间而言),就像MATLAB中的矢量化比循环更有效。 – Antimony