C# 在C中迭代泛型列表时的性能问题#
假设这些业务对象具有一些共同的属性:C# 在C中迭代泛型列表时的性能问题#,c#,visual-studio-2008,list,generics,C#,Visual Studio 2008,List,Generics,假设这些业务对象具有一些共同的属性: public class A { // Properties in common public int Common { get; set; } public string aValue { get; set; } // Some other goes here. } public class B { // Properties in common public int Common { get; set;
public class A
{
// Properties in common
public int Common { get; set; }
public string aValue { get; set; }
// Some other goes here.
}
public class B
{
// Properties in common
public int Common { get; set; }
public string bValue { get; set; }
// Some other goes here.
}
在我们的业务逻辑中,我们有两个类似的列表:
List<A> aList = new List<A>();
List<B> bList = new List<B>();
是否有人知道更好的方法来改进此操作,因为它会导致我们的应用程序花费太多时间才能完成
谢谢,将bList复制到一个字典类型的容器中,使用Common作为键,并在循环中使用它,而不是bList本身。这不会很好地执行,因为列表上的
Find
是线性的。得到的算法是O(n^2)
您应该从公共属性的bList
中创建一个Dictionary
,并按键查找,而不是使用Find
进行搜索;字典查找是分期摊销的,因此它将使您的算法在列表长度上呈线性
var dict = bList.ToDictionary(b => b.Common);
foreach (A a in aList) {
B b;
if (dict.TryGetValue(a.Common, out b) {
b.bValue = a.aValue;
}
}
为了高效地查找某个值,给定某个键,您将不使用列表,而是使用字典。在列表中查找特定项需要O(N),在字典中查找特定项需要O(1)
Dictionary bDict=newdictionary();
foreach(B B在bList中)bDict.Add(B.Common,B);
foreach(在列表中为A){
if(bDict.ContainsKey(通用))
bDict[a.Common].bValue=a.aValue;
}
我相信,如果您在linq中进行联接,它将为您在两个列表上进行哈希联接,这将节省您手动创建字典的时间,正如其他答案中所建议的那样。我在这台机器上没有studio来为您提供示例,稍后将尝试更新
如果项目数量非常少,Linq甚至可能足够聪明,不会触发哈希连接
编辑:
让这样的东西旋转一下:
var joined = from a in aList
join b in bList on a.Common equals b.Common
select new {
A = a,
B = b
};
foreach (var item in joined)
{
item.B.bValue = item.A.aValue;
}
我不相信100个元素会导致任何性能问题。有多少?@gdoron这取决于你调用此函数的频率:)@gdoron我想我忘了提到该应用程序是针对Windows Mobile设备的,因此该应用程序受到移动设备资源的限制。答案很好,包括大O:D它不就是
B=dict[a.Common];如果(b!=null){b.bValue=a.aValue;}
@gdoron很遗憾,如果项目不在那里,[]
操作符将失败TryGetValue
是一个比包含+[]
更简单的选择,因为它可以避免按键进行额外的查找。+1这是我会给出的答案。使用join还可以避免使用TryGetValue或其他方法来处理源列表中不匹配的项。
Dictionary<int, B> bDict = new Dictionary<int, B>();
foreach (B b in bList) bDict.Add(b.Common, b);
foreach (A a in aList) {
if (bDict.ContainsKey(a.Common))
bDict[a.Common].bValue = a.aValue;
}
var joined = from a in aList
join b in bList on a.Common equals b.Common
select new {
A = a,
B = b
};
foreach (var item in joined)
{
item.B.bValue = item.A.aValue;
}