【发布时间】:2011-10-26 04:11:42
【问题描述】:
我这里有一个代码,它使用 linq 为工程师列表生成 XML。我的问题是有什么方法可以改进和加速这种方法
public static string CreateXMLforEngineersByLinq(List<Engineers> lst)
{
string x = "<Engineers>\n";
x += string.Concat(lst.Select(s =>
string.Format("<Engineer>\n<LicenseID>{0}</LicenseID>\n<LastName>{1}</LastName>\n<FirstName>{2}</FirstName>\n<MiddleName>{3}</MiddleName>\n</Engineer>\n",
s.LicenseID, s.LastName, s.FirstName, s.MiddleName)));
return x + "</Engineers>";
}
结果:
嗨,下面的代码是为我添加的,以显示我产生更多答案的方法的实际速度,欢迎修改再次感谢那些在这里提供帮助的人:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using test.Classes;
namespace test.LINQ
{
public static class BatchOperations
{
delegate string Operations(List<Engineers> i);
public static List<int> BatchAddition(List<int> lstNumbers)
{
lstNumbers = (from nl in lstNumbers
select nl + 2).ToList();
return lstNumbers;
}
public static string CreateXMLforEngineersTheSimpleWay(IEnumerable<Engineers> lst)
{
StringBuilder x = new StringBuilder();
x.AppendLine("<Engineers>");
foreach (var s in lst)
{
x.AppendFormat("<Engineer>\n<LicenseID>{0}</LicenseID>\n<LastName>{1}</LastName>\n<FirstName>{2}</FirstName>\n<MiddleName>{3}</MiddleName>\n</Engineer>\n",
s.LicenseID,
s.LastName,
s.FirstName,
s.MiddleName);
}
x.AppendLine("</Engineers1>");
return x.ToString();
}
public static string CreateXMLforEngineersByLinq(List<Engineers> lst)
{
string x = "<Engineers>\n";
x += string.Concat(lst.Select(s =>
string.Format("<Engineer>\n<LicenseID>{0}</LicenseID>\n<LastName>{1}</LastName>\n<FirstName>{2}</FirstName>\n<MiddleName>{3}</MiddleName>\n</Engineer>\n",
s.LicenseID, s.LastName, s.FirstName, s.MiddleName)));
return x + "</Engineers2>";
}
public static string CreateXMLforEngineersByLoop(List<Engineers> lst)
{
string XmlForEngineers = "<Engineers>";
foreach (Engineers item in lst)
{
XmlForEngineers += string.Format("<Engineer>\n<LicenseID>{0}</LicenseID>\n<LastName>{1}</LastName>\n<FirstName>{2}</FirstName>\n<MiddleName>{3}</MiddleName>\n</Engineer>\n"
, item.LicenseID, item.LastName, item.FirstName, item.MiddleName);
}
XmlForEngineers += "</Engineers3>";
return XmlForEngineers;
}
public static void ShowEngineersByLicense()
{
List<Engineers> lstEngr = new List<Engineers>();
Engineers tom = new Engineers();
tom.FirstName = "Tom";
tom.MiddleName = "Brook";
tom.LastName = "Crook";
tom.LicenseID = "1343-343434";
Engineers ken = new Engineers();
ken.FirstName = "ken";
ken.MiddleName = "Brook";
ken.LastName = "Crook";
ken.LicenseID = "1343-343434";
Engineers ben = new Engineers();
ben.FirstName = "ben";
ben.MiddleName = "Brook";
ben.LastName = "Crook";
ben.LicenseID = "1343-343434";
for (int y = 0; y <= 1000; y++)
{
lstEngr.Add(tom);
lstEngr.Add(ken);
lstEngr.Add(ben);
}
List<Operations> j = new List<Operations>();
j.Add(a => CreateXMLforEngineersTheSimpleWay(lstEngr));
j.Add(i => CreateXMLforEngineersByLinq(lstEngr));
j.Add(i => CreateXMLforEngineersByLoop(lstEngr));
DateTime start, end;
TimeSpan diff1 = new TimeSpan();
foreach (Operations currentMethod in j)
{
start = DateTime.Now;
Console.Write(currentMethod(lstEngr));
end = DateTime.Now;
diff1 = end - start;
Console.WriteLine(diff1);
Console.Write("\n\n");
}
}
}
}
【问题讨论】:
-
您应该重新进行基准测试。 1:您需要列表中的 3 人以上才能产生显着差异(尝试 10,000 人)。 2:他们需要分配不同的字符串(这很可能是现实世界中的情况)。 C# 具有不可变的字符串,因此拥有相同的 4 个字符串会非常快。使用 Guid.NewGuid().ToString()。第三,您需要多次运行测试(例如 100 次),然后取平均值。我很难相信 string += string 的表现优于 StringBuilder
-
5000人跑,我得到的结果是:LINQ: 0.019ms, For-Loop: 12.059 seconds, Simple way: 0.010ms
-
我很欣赏@Rob 的评论
-
我再次用 300k 记录对其进行了基准标记,但这次 linq 来得更快
-
@Allan:这是您应用程序的瓶颈吗?如果不是,那为什么还要优化它呢?只需尽可能编写最简单、最易于维护的代码,并且仅在必要时对其进行优化。如果您正在序列化,您通常会写入磁盘或网络,这几乎肯定会使您可以进行的任何内存优化相形见绌。话虽如此,如果这需要 12 秒,则可能发生了一些奇怪的事情,在这种情况下值得一看。