我有一个正在使用的自定义对象列表。我需要找到匹配的对象,并将两个属性保存到对象,然后继续前进。我情不自禁地认为我处理这些对象的方法不太理想。考虑到我正在处理大量的数据(在本例中是一个包含大约10000个对象的列表,但在其他情况下则要大得多),我希望有任何信息可以帮助我优化这个过程。
List<WebListingVerification> listings = new List<WebListingVerification>(); //This list is fully populated, and is actually passed into the function.
string sku = reader["vsr_sku"].ToString();
string vendorName = reader["v_name"].ToString();
string vendorSku = reader["vsr_vendor_sku"].ToString();
WebListingVerification listing = listings.Find(x => x.SKU == sku);
if(listing != null)
{
listings.Remove(listing);
listing.Vendor = vendorName;
listing.VendorSKU = vendorSku;
listings.Add(listing);
}正如您在上面看到的,我首先删除列表,然后编辑它,然后重新添加它。我想有一种方法可以安全地编辑列表中的对象,而不需要运行Remove / Add,这会有很大帮助,但我似乎找不到如何做到这一点。我不确定您是否可以在listings.Find调用(listings.Find(x => x.SKU == sku).Vendor = "vendor")之外执行一个复合函数,但这是不安全的,因为在这种情况下,无论如何都会出现空返回。
任何帮助优化这将是非常感谢的。
编辑
谢谢您的评论,我不明白List.Find函数调用的结果实际上是指向列表中的对象的指针,而不是对象的副本。这就澄清了我的问题!
此外,感谢您的补充答复。我在寻找一个简单的改进,主要是删除Add / remove例程,但是附加的答案为我提供了一些关于如何在将来编写这些例程的好主意,这可能会带来一些显著的性能改进。在过去的几个月里,我一直专注于报告任务,所以这个示例片段非常类似于我从各种源数据库收集数据的100个不同的例程。再次,我非常感谢您的投入。
发布于 2016-03-10 18:06:28
要加快查找速度,首先可以将列表转换为字典。注意,如果您的update方法是一个方法,则不应该在方法内部进行转换,而应该在update循环之外进行转换。
var dictionary = listings.ToDictionary(l => l.SKU);并从字典中获得带有sku值的项。
WebListingVerification listing;
if (dictionary.TryGetValue(sku, out listing))
{
listing.Vendor = vendorName;
listing.VendorSKU = vendorSku;
}发布于 2016-03-10 18:19:10
public class WebListingVerification
{
public string Sku { get; set; }
public string VendorName { get; set; }
public string VendorSku { get; set; }
}
public class ListingManager : IEnumerable <WebListingVerification>
{
private Dictionary<string, WebListingVerification> _webListDictionary;
public ListingManager(IEnumerable <WebListingVerification> existingListings)
{
if (existingListings == null)
_webListDictionary = new Dictionary<string, WebListingVerification>();
else
_webListDictionary = existingListings.ToDictionary(a => a.Sku);
}
public void AddOrUpdate (string sku, string vendorName, string vendorSku)
{
WebListingVerification verification;
if (false == _webListDictionary.TryGetValue (sku, out verification))
_webListDictionary[sku] = verification = new WebListingVerification();
verification.VendorName = vendorName;
verification.VendorSku = vendorSku;
}
public IEnumerator<WebListingVerification> GetEnumerator()
{
foreach (var item in _webListDictionary)
yield return item.Value;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}发布于 2016-03-10 18:15:11
如果您的商品是唯一的,我可以建议您使用HashSet<T>吗?
HashSet<WebListingVerification> listings = new HashSet<WebListingVerification>();
string sku = reader["vsr_sku"].ToString();
string vendorName = reader["v_name"].ToString();
string vendorSku = reader["vsr_vendor_sku"].ToString();
if(listings.Contains(listing))
{
listings.Remove(listing);
listing.Vendor = vendorName;
listing.VendorSKU = vendorSku;
listings.Add(listing);
}您必须在IEqualityComparer<T>对象上滚动自己的WebListingVerification接口,并在SKU上匹配,我认为这是唯一的。
public class WebListingVerification : IEqualityComparer<WeblistingVerification>
{
public string Sku { get; set; }
public bool Equals(WebListingVerification obj, WebListingVerification obj2)
{
if (obj == null && obj2 == null)
return true;
else if (obj == null | obj2 == null)
return false;
else if (obj.Sku == obj2.Sku)
return true;
else
return false;
}
public int GetHashCode(WebListingVerification obj)
{
return Sku.GetHashCode();
}
}在这样的大型数据集中,HashSet.Contains()的性能是惊人的。
https://stackoverflow.com/questions/35923907
复制相似问题