创建XML的最快,最有效的方法

时间:2012-01-28 17:39:22

标签: java xml performance xml-serialization

在Java中创建XML文档的最快,最有效的方法是什么?那里有很多库(woodstox,xom,xstream ......),只是想知道是否有人有任何输入。我应该采用代码生成方法(因为xml架构是众所周知的)?或者在运行时采用反射方法?

使用其他信息进行编辑:

  1. 定义良好的XML Schema可用且很少更改
  2. 要求是将java对象转换为XML,而不是反之亦然
  3. 每秒有数千个java对象转换为XML
  4. 代码生成,代码复杂性,配置,维护等是性能更高的。

6 个答案:

答案 0 :(得分:14)

如果我要创建一个非常简单的XML内容,我会坚持使用JDK api,不会引入任何第三方依赖。

对于简单的XML,如果我要将XML文件映射到Java类(反之亦然),我会选择JAXBSee this tutorial看看它有多容易。

现在

如果我要使用常量方案创建一些更复杂的XML输出,我可能会使用一些模板引擎FreemarkerThymeleaf看起来也不错。

最后。

如果我要非常有效地创建巨大的XML文件,我会使用SAX parser

我希望您现在明白,您有很多可能性 - 根据您的需求选择最佳匹配:)

玩得开心!

答案 1 :(得分:5)

试试Xembly,一个小型开源库,使这个XML创建过程非常简单直观:

String xml = new Xembler(
  new Directives()
    .add("root")
    .add("order")
    .attr("id", "553")
    .set("$140.00")
).xml();

Xembly是本机Java DOM的包装器,是一个非常轻量级的库(我是开发人员)。

答案 2 :(得分:2)

首先,序列化是正确的很重要。手写的序列化器通常不是。例如,他们倾向于忘记字符串“]]>”不能出现在文本节点中。

如果你是一个有能力的Java程序员,编写你自己的正确和快速的序列化程序并不困难,但是因为一些非常有能力的Java程序员在此之前我认为你不可能在足够的余地使得编写自己的代码值得花时间。

除了大多数通用库可能会通过提供序列化选项(如缩进,编码或选择行结尾)而放慢一点。您可以通过避免不需要的功能来挤出额外的性能。

此外,一些通用库可能会检查您向它们抛出的内容的格式,例如检查是否声明了名称空间前缀(或者如果没有,则声明它们)。如果不进行检查,您可以加快速度。另一方面,您可能会创建一个快速的库,但是可以使用它。将表现置于所有其他目标之上几乎总是一个错误。

至于可用库的性能,请测量它们,并告诉我们您发现了什么。

答案 3 :(得分:1)

我所知道的最好的方法是使用能够创建节点的XPath引擎。 XMLBeam能够做到这一点(在JUnit测试中):

    public interface Projection {

    @XBWrite("/create/some/xml/structure[@even='with Predicates']")
    void demo(String value);
}

@Test
public void demo() {
    Projection projection = new XBProjector(Flags.TO_STRING_RENDERS_XML).projectEmptyDocument(Projection.class);
    projection.demo("Some value");
    System.out.println(projection);
 }

此程序打印出来:

<create>
   <some>
      <xml>
        <structure even="with Predicates">Some value</structure>
      </xml>
   </some>
</create>

答案 4 :(得分:1)

受到 Petr 回答的启发,我花了一天的大部分时间来实施这样的基准测试,在此过程中阅读了大量关于 JMH 的内容。项目在这里:https://github.com/62mkv/xml-serialization-benchmark

结果如下:

Benchmark                                          (N)   Mode  Cnt    Score    Error  Units
XmlSerializationBenchmark.testWithJaxb              50  thrpt    5  216,758 ± 99,951  ops/s
XmlSerializationBenchmark.testWithXStream           50  thrpt    5   40,177 ±  1,768  ops/s
XmlSerializationBenchmark.testWithXmlStreamWriter   50  thrpt    5  520,360 ± 14,745  ops/s

我没有包括 Xembly,因为根据它的描述,对于这种特殊情况,它看起来有点矫枉过正。

我有点惊讶 XStream 有如此糟糕的记录,因为它来自 ThoughtWorks,但可能只是因为我没有针对这个特殊情况对其进行足够好的定制。 XMLStreamWriter 的默认 Java 8 标准库 StAX 实现在性能方面是最好的。但就开发者体验而言,XStream 是最简单易用的,而 XMLStreamWriter 也需要更容易出错的努力才能完全实现;而 JAXB 在两项提名中均名列第二。

PS:非常欢迎改进套件的反馈和建议!

答案 5 :(得分:0)

使用XMLStreamWriter。

我运行了一个微基准测试,将其中的一百万个序列化:

@XmlRootElement(name = "Root")
public class Root {
    @XmlAttribute
    public String attr;
    @XmlElement(name = "F1")
    public String f1;
    @XmlElement(name = "F2")
    public String f2;
}

具有以下结果:

JAXB: 3464 millis (<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Root attr="at999999"><F1>x999999</F1><F2>y999999</F2></Root>)
XMLStreamWriter: 1604 millis (<?xml version="1.0" ?><Root attr="at999999"><F1>x999999</F1><F2>y999999</F2></Root>)
Xembly: 25832 millis (<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Root attr="at999999">
<F1>x999999</F1>
<F2>y999999</F2>
</Root>
)
StringBuilder: 60 millis (<?xml version="1.0" encoding="UTF-8"><Root attr=")at999999"><F1>x999999</F1><F2>y999999</F2></Root>)
StringBuilder w/escaping: 3806 millis (<?xml version="1.0" encoding="UTF-8"><Root attr="at999999"><F1>x999999</F1><F2>y999999</F2></Root>)

给出:

  • StringBuilder:60毫秒
  • XMLStreamWriter:1604毫秒
  • JAXB:3464毫秒
  • 具有非常原始的转义符的StringBuilder:3806 ms
  • Xembly:25832毫秒
  • 还有很多我没有尝试过的

StringBuilder是效率最高的,但这是因为它不需要遍历所有搜索“,&,<和>的文本并将其转换为XML实体。