将字符串转换为XML的最快方法

3
我们有一个XMLIDList助手,它使用+=(:()。我正在寻找的是,最快的方法是什么?这以前不是问题,因为列表的项目<10个,但我们添加了一个新功能,可以传递15k个项目。正如您所想象的那样,速度很慢。
  public static string EncodeGuidListToXML(IList<Guid> elementsToEncode)
        {
            if (elementsToEncode == null || elementsToEncode.Count == 0)
                return String.Empty;

            string beginItemNode = BeginItemNode;
            string endItemNode = EndItemNode; 
            
            string xml = BeginRootNode;

            foreach (Guid item in elementsToEncode)
            {
                xml += beginItemNode + item.ToString().ToUpper() + endItemNode;
            }

            xml += EndRootNode;

            return xml;
        }
3个回答

7
使用 StringBuilder 可以带来更好的性能提升。
由于它“表示一个可变字符的字符串”,所以在字符串操作方面比直接连接字符串要快得多,因为它不必每次都复制字符串。

是的 - 我一开始就改用那个了。我只是希望有更好的东西呵呵 :) - Steoates

4
最好的方法是不要一开始就使用字符串拼接,个人认为应该使用XML API。建立一个XDocumentXmlDocument,然后在最后将其转换为字符串。虽然你现在的逻辑相当简单,但一旦你需要转义或类似的值,你真的不想复制一个真正的XML API的所有逻辑...所以使用现有的API。
这是一个重写当前方法的示例:
public static string EncodeGuidListToXml(IList<Guid> guids)
{
    if (elementsToEncode == null || elementsToEncode.Count == 0)
    {
        return "";
    }
    return new XDocument(
        new XElement("Root",
            guids.Select(guid => new XElement("Item", guid.ToString().ToUpper()))
        )).ToString();

}

如果你真的想坚持直接构建字符串,StringBuilder确实是正确的选择。


如果顺序不重要且列表通常很大,有人可以使用.AsParallel()对其进行并行处理吗? - Alex Bagnolini
顺序并不重要,但大多数情况下这些列表最多只有50个项目,但也有一些情况可能超过100个,每一个小帮助都很重要! - Steoates

3

我使用了标准的字符串方法、StringBuilder类方法以及利用XDocument和XElement类的方法进行了一些测试。在短列表中,StringBuilder类获胜,但对于较大的列表,XML类给出了相当的时间。下面是我使用的测试代码:

List<string> list;
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();

protected void Page_Load(object sender, EventArgs e)
{
    list = Enumerable.Range(0, 15000).Select(i => i.ToString()).ToList();
    UsingStrings();
    UsingStringBuilder();
    UsingXDocument();
}

private void UsingStrings()
{
    timer.Reset();
    timer.Start();
    string beginItemNode = "<Node>";
    string endItemNode = "</Node>";
    string xml = "<Root>";

    foreach (string item in list)
    {
        xml += beginItemNode + item + endItemNode;
    }

    xml += "</Root>";
    timer.Stop();
    Response.Write(string.Format("Strings time:{0}<br />", timer.Elapsed.Ticks));
}

private void UsingStringBuilder()
{
    timer.Reset();
    timer.Start();
    StringBuilder sb = new StringBuilder();
    sb.Append("<Root>");

    foreach (string item in list)
    {
        sb.AppendFormat("<Node>{0}</Node>", item);
    }

    sb.Append("</Root>");
    timer.Stop();
    Response.Write(string.Format("StringBuilder time:{0}<br />", timer.Elapsed.Ticks));
}

private void UsingXDocument()
{
    timer.Reset();
    timer.Start();
    XDocument xDoc = new XDocument();
    xDoc.Add(new XElement("Root"));
    foreach (var item in list)
    {
        XElement element = new XElement("Node", item);
        xDoc.Root.Add(element);
    }
    timer.Stop();
    Response.Write(string.Format("XDocument time:{0}<br />", timer.Elapsed.Ticks));
}

在我的机器上进行的上述测试得到了以下结果:
First run:
    Strings time:239750613
    StringBuilder time:55509
    XDocument time:61904
Second run:

    Strings time:289422753
    StringBuilder time:198595
    XDocument time:80032

如果您想以无格式的字符串形式显示XDocument XML,请使用以下方法:
string xml = xDoc.ToString(SaveOptions.DisableFormatting);

修改:我最初说XDocument要快得多,但运行测试几次后,它似乎与StringBuilder方法基本相同,尽管它似乎更一致,而有时StringBuilder更快,有时则慢得多。显然,与使用字符串相比,使用这两种方法要快得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接