我正在处理一个类(Widget),该类具有大量真实世界的数字属性(例如高度、长度、重量、成本等)。有不同类型的小部件(sprockets、cogs等),但每个小部件都共享完全相同的属性(当然,各个小部件的值将不同,但它们都有重量、长度等)。我有数千个每种小部件(1,000个齿轮,1,000个链轮等)。
我需要对这些属性执行大量计算(例如计算1000个不同小部件的属性的加权平均值)。对于加权平均值,我针对每个小部件类型有不同的权重(即,我可能更关心齿轮的长度而不是链轮)。
现在,我正在每个小部件中存储所有属性,在其中使用Dictionary<string,double>。然后,我有一些计算器类,它们将每个属性的权重存储为Dictionary<WidgetType,Dictionary<string,double>>。要计算每个小部件的加权平均值,我只需迭代其属性字典键,如下所示:
所以这个方案运行良好,易于阅读和维护,但是当基于某些分析数据有1000多个小部件时速度非常慢。我的属性名称的宇宙在应用程序的使用期间已知且不会改变,因此我想知道有哪些更好的选择。我能想到的几种方式是:
我需要对这些属性执行大量计算(例如计算1000个不同小部件的属性的加权平均值)。对于加权平均值,我针对每个小部件类型有不同的权重(即,我可能更关心齿轮的长度而不是链轮)。
现在,我正在每个小部件中存储所有属性,在其中使用Dictionary<string,double>。然后,我有一些计算器类,它们将每个属性的权重存储为Dictionary<WidgetType,Dictionary<string,double>>。要计算每个小部件的加权平均值,我只需迭代其属性字典键,如下所示:
double weightedAvg = 0.0;
foreach (string attibuteName in widget.Attributes.Keys)
{
double attributeValue = widget.Attributes[attributeName];
double attributeWeight = calculator.Weights[widget.Type][attributeName];
weightedAvg += (attributeValue * attributeWeight);
}
所以这个方案运行良好,易于阅读和维护,但是当基于某些分析数据有1000多个小部件时速度非常慢。我的属性名称的宇宙在应用程序的使用期间已知且不会改变,因此我想知道有哪些更好的选择。我能想到的几种方式是:
1)将属性值和权重存储为double []数组。我认为这可能是最有效的选项,但是我需要确保这些数组始终按正确顺序存储在小部件和计算器之间。这也将数据从元数据中分离出来,因此我需要在某处存储一个数组(?),该数组将属性名称映射到属性值和权重的double []中的索引。
2)将属性值和权重存储为不可变的结构体。我喜欢这个选项,因为我不必担心排序问题,而且数据是“自文档”的。但是,在代码中循环遍历这些属性是否有简单的方法?我有近100个属性,因此我不想在代码中硬编码所有这些内容。我可以使用反射,但我担心这会导致更大的性能损失,因为我正在循环遍历如此多的小部件,并且必须对每一个进行反射。
是否有其他选择?