【问题标题】:Optimizing speed of parsing XML file using VTD-XML使用 VTD-XML 优化解析 XML 文件的速度
【发布时间】:2012-02-13 20:01:55
【问题描述】:

我正在使用 VTD-XML 解析大量 XML 文件。我不确定我是否正确使用了该工具 - 我想是的,但是解析文件花费的时间太长了。

xml 文件(DATEXII 格式)是 HD 上的压缩文件。解压后它们大约有 31MB 大,包含超过 850.000 行文本。我只需要提取几个字段并将它们存储在数据库中。

import org.apache.commons.lang3.math.NumberUtils;
...

private static void test(File zipFile) throws XPathEvalException, NavException, XPathParseException {
    // init timer
    long step1=System.currentTimeMillis();

    // open file to output extracted fragments
    VTDGen vg = new VTDGen();
    vg.parseZIPFile(zipFile.getAbsolutePath(), zipFile.getName().replace(".zip",".xml"),true);

    VTDNav vn = vg.getNav();

    AutoPilot apSites = new AutoPilot();
    apSites.declareXPathNameSpace("ns1", "http://schemas.xmlsoap.org/soap/envelope/");
    apSites.selectXPath("/ns1:Envelope/ns1:Body/d2LogicalModel/payloadPublication/siteMeasurements");
    apSites.bind(vn);

    long step2=System.currentTimeMillis();
    System.out.println("Prep took "+(step2-step1)+"ms; ");

    // init variables
    String siteID, timeStr;
    boolean reliable;
    int index, flow, ctr=0;
    short speed;
    while(apSites.evalXPath()!=-1) {

        vn.toElement(VTDNav.FIRST_CHILD, "measurementSiteReference");
        siteID = vn.toString(vn.getText());

        // loop all measured values of this measurement site
        while(vn.toElement(VTDNav.NEXT_SIBLING, "measuredValue")) {
            ctr++;

            // extract index attribute
            index = NumberUtils.toInt(vn.toString(vn.getAttrVal("index")));

            // go one level deeper into basicDataValue
            vn.toElement(VTDNav.FIRST_CHILD, "basicDataValue");

            // we need either FIRST_CHILD or NEXT_SIBLING depending on whether we find something
            int next = VTDNav.FIRST_CHILD;
            if(vn.toElement(next, "time")) {
                timeStr = vn.toString(vn.getText());
                next = VTDNav.NEXT_SIBLING;
            }

            if(vn.toElement(next, "averageVehicleSpeed")) {
                speed = NumberUtils.toShort(vn.toString(vn.getText()));
                next = VTDNav.NEXT_SIBLING;
            }

            if(vn.toElement(next, "vehicleFlow")) {
                flow = NumberUtils.toInt(vn.toString(vn.getText()));
                next = VTDNav.NEXT_SIBLING;
            }

            if(vn.toElement(next, "fault")) { 
                reliable = vn.toString(vn.getText()).equals("0");
            }

            // insert into database here...

            if(next==VTDNav.NEXT_SIBLING) {
                vn.toElement(VTDNav.PARENT);
            }
            vn.toElement(VTDNav.PARENT);
        }

    }
    System.out.println("Loop took "+(System.currentTimeMillis()-step2)+"ms; ");
    System.out.println("Total number of measured values: "+ctr);
}

我的 XML 文件的上述函数的输出是:

Prep took 25756ms; 
Loop took 26889ms; 
Total number of measured values: 112611

现在实际上没有数据插入到数据库中。现在的问题是我每分钟都会收到一个这些文件。现在总解析时间接近 1 分钟,因为下载文件大约需要 10 秒,而且我需要将内容存储在数据库中,所以我现在正在实时运行。

有什么办法可以加快速度吗?我尝试过但无济于事的事情:

  • 对所有字段使用自动驾驶仪,这实际上使第二步慢了 30000 毫秒
  • 自己解压文件并将字节数组解析为VTD,这没有任何区别
  • 自己使用 BufferedReader readLine() 循环文件,但这也不够快

是否有人认为可以加快速度,或者我是否需要开始考虑更重的机器/多线程?当然,每分钟 850.000 行(每天 12 亿行)已经很多了,但我仍然觉得解析 31MB 的数据不应该花一分钟...

【问题讨论】:

  • 您能否将问题发布到 vtd-xml 邮件列表中,我很乐意帮助您解决问题。

标签: java xml-parsing vtd-xml


【解决方案1】:

您可以尝试立即解压缩文件夹并将每个 xml 文件的值存储在一个数组中

File[] files = new File("foldername").listFiles();

然后你可以循环遍历每个文件,我不确定这是否会加快速度,但值得一试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 2015-10-20
    • 2010-10-29
    相关资源
    最近更新 更多