我正在尝试重构一些运行缓慢的代码,这些代码使用多个数据表的嵌套循环来编写XML。我读到使用linq编写xml会更快。我不太熟悉linq,所以我希望能在这里得到一些帮助。
我需要提到的一些事情是当前架构使用webservice,它在dataTables中向我们返回数据。然后我们遍历数据表(迭代地),并且有几个导致几个嵌套循环。
示例:
dt1 = Webservice.getStuff();
for each (datarow r1 in dt1.Rows) {
dt2 = Webservice.getMoreStuff(r1[col1], r1[col2]);
// write out some xml
for each (datarow r2 in dt2.Rows) {
dt3 = Webservice.getEvenMoreStuff(r2[col1], r2[col2]);
// write out more xml
for each (datarow r3 in dt3.Rows) {
// write out more xml
}
}
}
正如您所看到的,显而易见的原因,这非常缓慢。有没有办法加速使用linq?你们有什么建议作为一种更有效的方法来重构这个?如果细节含糊不清,我很抱歉......
我感谢任何人提供的任何帮助。
答案 0 :(得分:14)
在这种情况下编写XML并不会减慢你的速度。与进行所有Web服务调用所花费的时间相比,该速度应该可以忽略不计。
我不会专注于编写XML,而是试图弄清楚如何压缩Web服务调用的数量,以便您可以一次获取所有数据,而不是像这样进行嵌套调用。
答案 1 :(得分:4)
我担心你的需要无法治愈。因为我很确定是什么让这个方法变慢所以不是你写出xml的方式,而是你获取数据的方式。如果写出xml会有任何改进,那就不会有明显的比例。我建议你修改你获取数据的方式。尽量减少WebService调用的数量。
答案 2 :(得分:3)
听起来您需要首先剖析您的应用 - 也许ANTS或类似的免费试用版适合您。
答案 3 :(得分:1)
如果你想使用Linq2Xml,你还需要Linq2Datasets。
通过这种方式,您可以将嵌套for循环更改为Linq查询并选择XML。
我确实希望使用XmlWriter可能会更快,并且肯定会使用更少的内存。但是要写一些东西会更多。
答案 4 :(得分:1)
使用linq到xml和linq到数据集,您可以像这样创建自己的xml:
static void Main(string[] args)
{
DataTable t = getStuff("test");
var xml = new XElement("Main", from row in t.AsEnumerable()
select new XElement("firstlevel",
new XAttribute("a", row["a"]),
new XAttribute("b", row["b"]),
from row2 in getStuff(row["a"].ToString()).AsEnumerable()
select new XElement("secondlevel",
new XAttribute("a", row2["a"]),
new XAttribute("b", row2["b"]),
from row3 in getStuff(row2["a"].ToString()).AsEnumerable()
select new XElement("thirdlevel",
new XElement("a", row3["a"]),
new XElement("b", row3["b"])))));
Console.WriteLine(xml.ToString());
}
private static DataTable getStuff(string s)
{
Random r=new Random(s.GetHashCode());
DataTable t = new DataTable();
t.Columns.Add("a");
t.Columns.Add("b");
for (int i = 0; i < 2; i++)
{
t.Rows.Add (r.Next().ToString(), r.Next().ToString());
}
return t;
}
答案 5 :(得分:0)
你必须重新考虑你的解决方案,以摆脱所有循环的WS调用。这是一个严重的性能下降。
答案 6 :(得分:0)
您没有说明编写XML的方式或编写XML的位置。
如果您正在写一个字符串。停下来,然后写一个流。
如果要写入缓冲字符串,请查看缓冲区的大小。如果您是从ASP.NET页面或处理程序编写的,则定期调用Response.Flush()。
这里有一个平衡,因为写入缓冲区几乎总是比写入流更快。但是,写入自动调整大小缓冲区的速度越慢,调整大小就越大。更重要的是,无论处理什么,XML都无法开始行动,直到它开始接收一些,直到第一次刷新之后才会发生。
因此,可能存在改进的余地,尽管对Web服务的调用可能超过可以获得的收益。也许这也可以改进,如果你重写webservice响应的解析,以便在解析它们时yields
项,这意味着你可以在收到整个响应之前开始处理响应。