C# 这个小小的c函数有什么优化技巧吗?
我得到了一个9MB大的XML文件。显然,它坏了 我想检查是否有任何级别2的同级元素具有相同值的属性Id 目前速度太慢了。我可以对这段代码进行什么样的优化 编辑以包含一些提示C# 这个小小的c函数有什么优化技巧吗?,c#,xml,performance,C#,Xml,Performance,我得到了一个9MB大的XML文件。显然,它坏了 我想检查是否有任何级别2的同级元素具有相同值的属性Id 目前速度太慢了。我可以对这段代码进行什么样的优化 编辑以包含一些提示 您正在重复检查,因此可以执行int j=i+1,而不是从0开始 你不必检查我!=然后,重复检查,这样就可以执行int j=i+1,而不是从0开始 你不必检查我!=那么 在for循环中,将列表计数存储到变量,而不是访问count属性 对于int i=0,idCount=ids.Count;i++ { } 将ID[i]存储到局部
您正在重复检查,因此可以执行int j=i+1,而不是从0开始
你不必检查我!=然后,重复检查,这样就可以执行int j=i+1,而不是从0开始 你不必检查我!=那么 在for循环中,将列表计数存储到变量,而不是访问count属性 对于int i=0,idCount=ids.Count;i++ { } 将ID[i]存储到局部变量,而不是在集合中多次查找它 最大的变化是避免嵌套for循环。考虑改写。 编辑:进行了以下更改
private const string _pathToXml = @"C:\test.xml";
private static readonly List<object> _duplicateLeafs = new List<object>();
private static void Main()
{
var xml = ReadXml();
var elements = xml.Descendants();
FindDupes(elements);
}
private static void FindDupes(IEnumerable<XElement> elements)
{
foreach (var element in elements)
{
var subElements = element.Descendants();
var subElementsWithIds = subElements.Where(x => x.Attribute("Id") != null).ToList();
var ids = subElementsWithIds.Select(x => x.Attribute("Id")).ToList();
var duplicates = ids.GroupBy(s => s.Value).SelectMany(grp => grp.Skip(1)).Distinct().ToList();
if (duplicates != null)
{
_duplicateLeafs.AddRange(duplicates);
}
FindDupes(subElements);
}
}
在for循环中,将列表计数存储到变量,而不是访问count属性
对于int i=0,idCount=ids.Count;i++
{
}
将ID[i]存储到局部变量,而不是在集合中多次查找它
最大的变化是避免嵌套for循环。考虑改写。
编辑:进行了以下更改
private const string _pathToXml = @"C:\test.xml";
private static readonly List<object> _duplicateLeafs = new List<object>();
private static void Main()
{
var xml = ReadXml();
var elements = xml.Descendants();
FindDupes(elements);
}
private static void FindDupes(IEnumerable<XElement> elements)
{
foreach (var element in elements)
{
var subElements = element.Descendants();
var subElementsWithIds = subElements.Where(x => x.Attribute("Id") != null).ToList();
var ids = subElementsWithIds.Select(x => x.Attribute("Id")).ToList();
var duplicates = ids.GroupBy(s => s.Value).SelectMany(grp => grp.Skip(1)).Distinct().ToList();
if (duplicates != null)
{
_duplicateLeafs.AddRange(duplicates);
}
FindDupes(subElements);
}
}
您说要检查第2级子体,但FindDupes是递归的,所以每次调用都要递归检查foreach循环中的两个级别。您说要检查第2级子体,但FindDupes是递归的,所以递归检查foreach循环中的两个级别,每次调用。使用XmlReader并按顺序处理它,而不是从XDocument.Parse开始对它进行完整的解析。对于真正大的XML文件,我会使用[XmlReader]http://msdn.microsoft.com/en-us/library/system.xml.xmlreader%28v=vs.100%29.aspx 您可以用int j=i+1代替XDocument。您可以用int j=i+1代替从0开始。您说要检查级别2的子体,但FindDupes是递归的,所以每次调用都递归检查foreach循环中的两个级别。@dwerner噢。。。该死你说得太对了。我这边的哑巴。稍后将更新。请使用XmlReader并按顺序处理它,而不是从XDocument.Parse开始对其进行完整的解析。对于真正大的XML文件,我将使用[XmlReader]http://msdn.microsoft.com/en-us/library/system.xml.xmlreader%28v=vs.100%29.aspx 您可以用int j=i+1代替XDocument。您可以用int j=i+1代替从0开始。您说要检查级别2的子体,但FindDupes是递归的,所以每次调用都递归检查foreach循环中的两个级别。@dwerner噢。。。该死你说得太对了。我这边的哑巴。稍后将更新。如何避免嵌套for循环?请发布一个xml文件示例。任何xml都可以使用具有相同值Id属性的同级元素。如何避免嵌套for循环?请发布一个xml文件示例。任何xml都可以使用具有相同值Id属性的同级元素
<?xml version="1.0" encoding="utf-8" ?>
<persons>
<person Id="1">
<name>Michael</name>
<age>29</age>
</person>
<person Id="1">
<name>Rebecca</name>
<age>29</age>
</person>
<person Id="2">
<name>Matthew</name>
<age>29</age>
</person>
<person Id="2">
<name>Paul</name>
<age>29</age>
</person>
</persons>
Time: 2.8704708 seconds Lambda solution
Time: 692.043006 seconds Nested for loops