Gei*_*erg 5 .net c# linq performance
问题:我有2个类型的对象,让他们打电话Building和Improvement.大约有30个Improvement实例,而可能有1-1000 个实例Building.对于的每个组合Building和Improvement,我不得不执行一些繁重的计算,并且将结果存储在一个Result对象.
两个BuildingS和ImprovementS可通过一个整数ID来表示.
然后我需要能够:
Result给定Building和Improvement有效Result所有Improvements 执行聚合Building,如.Sum()和.Average()Result所有Buildings,对s 执行相同的聚合Improvement这将发生在Web服务器后端,因此内存可能是一个问题,但速度是最重要的.
思念至今:
Dictionary<Tuple<int, int>, Result>with <BuildingID, ImprovementID>作为键.这应该给我快速插入和单个查找,但我关心.Where()和.Sum()性能.BuildingIDs,一个用于ImprovementIDs,以及Resultas值.另外,构建两个Dictionary<int, int>将BuildingIDs和ImprovementIDs 映射到它们各自的数组行/列索引.这可能意味着最多1000+ Dictionarys,这会是一个问题吗?List<Tuple<int, int, Result>>.我认为这可能效率最低,有O(n)插入,但我可能是错的.我在这里错过了一个明显更好的选择吗?
编辑:原来它只是我感兴趣的聚合值(每个Building和每个Improvement); 看到我的回答.
感谢您的回答,测试代码非常有用:)
对我来说,解决方案是放弃 LINQ,并在繁重的计算之后直接手动执行聚合,因为无论如何我都必须迭代构建和改进的每个组合。
另外,我必须使用对象本身作为键,以便在将对象持久化到实体框架之前执行计算(即它们的 ID 均为 0)。
代码:
public class Building {
public int ID { get; set; }
...
}
public class Improvement {
public int ID { get; set; }
...
}
public class Result {
public decimal Foo { get; set; }
public long Bar { get; set; }
...
public void Add(Result result) {
Foo += result.Foo;
Bar += result.Bar;
...
}
}
public class Calculator {
public Dictionary<Building, Result> ResultsByBuilding;
public Dictionary<Improvement, Result> ResultsByImprovement;
public void CalculateAndAggregate(IEnumerable<Building> buildings, IEnumerable<Improvement> improvements) {
ResultsByBuilding = new Dictionary<Building, Result>();
ResultsByImprovement = new Dictionary<Improvement, Result>();
for (building in buildings) {
for (improvement in improvements) {
Result result = DoHeavyCalculation(building, improvement);
if (ResultsByBuilding.ContainsKey(building)) {
ResultsByBuilding[building].Add(result);
} else {
ResultsByBuilding[building] = result;
}
if (ResultsByImprovement.ContainsKey(improvement)) {
ResultsByImprovement[improvement].Add(result);
} else {
ResultsByImprovement[improvement] = result;
}
}
}
}
}
public static void Main() {
var calculator = new Calculator();
IList<Building> buildings = GetBuildingsFromRepository();
IList<Improvement> improvements = GetImprovementsFromRepository();
calculator.CalculateAndAggregate(buildings, improvements);
DoStuffWithResults(calculator);
}
Run Code Online (Sandbox Code Playgroud)
我这样做是因为我确切地知道我想要哪些聚合;如果我需要一种更动态的方法,我可能会选择 @MatthewWatson 的字典之类的东西。
| 归档时间: |
|
| 查看次数: |
954 次 |
| 最近记录: |