使用Java对100MB XML文件进行排序?

时间:2011-03-29 09:54:01

标签: java xml parsing

使用Java对100MB XML文件进行排序需要多长时间?

该文件包含具有以下结构的项目,我需要按事件

对它们进行排序
<doc>
    <id>84141123</id>
    <title>kk+ at Hippie Camp</title>
    <description>photo by SFP</description>
    <time>18945840</time>
    <tags>elphinstone tribalharmonix vancouver intention intention7 newyears hippiecamp bc sunshinecoast woowoo kk kriskrug sunglasses smoking unibomber møtleykrüg </tags>
    <geo></geo>
    <event>47409</event>
</doc>

我使用的是Intel Dual Duo Core和4GB RAM。

分钟?几小时?

感谢

4 个答案:

答案 0 :(得分:7)

以下是使用Saxon XQuery在100Mb输入文件上执行的类似任务的时间。

Saxon-EE 9.3.0.4J from Saxonica
Java version 1.6.0_20
Analyzing query from {for $i in //item order by location return $i}
Analysis time: 195 milliseconds
Processing file:/e:/javalib/xmark/xmark100.xml
Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
Building tree for file:/e:/javalib/xmark/xmark100.xml using class net.sf.saxon.tree.tiny.TinyBuilder
Tree built in 6158 milliseconds
Tree size: 4787932 nodes, 79425460 characters, 381878 attributes
Execution time: 3.466s (3466ms)
Memory used: 471679816

所以:解析输入文件和构建树大约需要6秒,排序时间为3.5秒。这是从命令行调用的,但从Java调用它将获得非常相似的性能。不要尝试自己编写排序 - 它只是一行查询,而且你不太可能匹配优化的XQuery引擎的性能。

答案 1 :(得分:2)

我会说几分钟 - 你应该能够在内存中完全做到这一点,所以使用sax解析器进行读取 - 排序 - 编写,对你的硬件来说应该不是问题

答案 2 :(得分:0)

我认为像这样的问题会更好地使用序列化进行排序。

  1. 将XML文件反序列化为'doc'的ArrayList。

  2. 使用直接Java代码,对事件属性应用sort,并在另一个变量中存储已排序的arraylist。

  3. 将已排序的'doc'ArrayList序列化为文件

答案 3 :(得分:0)

如果你在内存中这样做,你应该可以在10秒内完成。你会想要在2秒内完成这项任务,因为它会花费那么多时间来读/写磁盘。

此程序的使用量不应超过原始文件大小的4-5倍。在你的情况下大约500 MB。

String[] records = FileUtils.readFileToString(new File("my-file.xml")).split("</?doc>");
Map<Long, String> recordMap = new TreeMap<Long, String>();
for(int i=1;i<records.length;i+=2) {
    String record = records[i];
    int pos1 = record.indexOf("<id>");
    int pos2 = record.indexOf("</id>", pos1+4);
    long num = Long.parseLong(record.substring(pos1+3, pos2));
    recordMap.put(num, record);
}

StringBuilder sb = new StringBuilder(records[0]);
for (String s : recordMap.values()) {
    sb.append("<doc>").append(s).append("</doc>");
}
sb.append(records[records.length-1]);
FileUtils.writeStringToFile(new File("my-output-file.xml"), sb.toString());