[英]Counting the number of occurences of a number in C#
我目前正在使用字典计算事件结果的出现次数,我将其添加如下:
IDictionary<double, double> OutcomeCounter = new Dictionary<double, double>();
public void IncrementDict(IDictionary<double, double> dict, double newKey, double increment = 1)
{
if (!dict.ContainsKey(newKey))
{
dict.Add(newKey, 0);
}
dict[newKey] += increment;
}
然而,这占总模拟时间的 20% 左右,我想知道你们中是否有人对如何减少这个有一些好主意?
模拟产生了 100 亿个结果(总计约 50,000 个不同的结果),因此将每个结果存储在列表中将使用过多的 memory。
提前致谢。
性能问题可能是由于字典中已经存在的数字的单次增量需要三个字典查找。 每个增量的三个字典查找。
第一次字典查找发生在执行dict.ContainsKey(newKey)
时。 第二次和第三次查找发生在dict[newKey] += increment;
(一个查找从字典中获取要增加的值,另一个查找用增加的值替换旧值)。
一种想法是减少查找次数,理想情况下每次增量只有一次查找。 这意味着,字典中的值一旦存储就不应更改。
实现这一点的一种方法是使用 arrays (或具有计数值字段的自定义 class 的实例,这可能比使用数组有轻微的性能优势)用作保存计数值的容器,字典保存那些容器实例。 由于容器实例本身仍然存在并且永远不会在字典中被替换(只有容器中的计数值会改变),我们只需要一次字典查找即可获得适当的容器实例。 (当然,当在新键下存储新容器实例时,需要进行额外的查找。)
例如,这可能看起来像这样。 另请注意,我将计数值的类型更改为long
——我不确定你为什么在这里使用double
,除非你想实现小数增量(但不管是long
还是double
,方法都是一样的):
IDictionary<double, long[]> OutcomeCounter = new Dictionary<double, long[]>();
public void IncrementDict(IDictionary<double, long[]> dict, double newKey, long increment = 1)
{
if (dict.TryGetValue(newKey, out long[] container))
{
container[0] += increment;
}
else
{
dict[newKey] = new long[] { increment };
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.