如何解决Android上的XML解析性能问题

Kor*_*rbi 16 xml android saxparser xml-parsing simple-framework

我必须在Android上阅读大约约4000行的XML文件.首先,我尝试使用SimpleXML库,因为它最简单,我的HTC Desire花了大约2分钟.所以我想也许SimpleXML因为反射和这个库使用的所有其他魔法而变得如此之慢.我重写了我的解析器并使用了内置的DOM解析方法,并对性能有一些特别的关注.这有点帮助,但它仍然需要大约60秒,这仍然是完全不可接受的.经过一番研究后,我在developer.com上发现了这篇文章.有一些图表显示其他两种可用方法 - SAX解析器和Android的XML Pull-Parser - 同样很慢.在文章的最后,您将找到以下声明:

我遇到的第一个惊喜是这三种方法的速度有多慢.用户不希望在移动电话上等待很长时间,因此解析超过几十条记录的任何内容都可能需要采用不同的方法.

什么可能是"不同的方法"?如果你有超过"几十条记录"怎么办?

Ste*_*vie 34

原始答案,2012年

(注意:请务必阅读下面的2016年更新!)

我刚刚对Android(和其他平台)上的解析器进行了一些性能测试.正在解析的XML文件只有500行左右(它是一个Twitter搜索Atom提要),但是Pull和DOM解析可以在Samsung Galaxy S2或Motorola Xoom2上每秒翻译大约5个这样的文档.OP中使用的SimpleXML(图表中的粉红色)与DOM解析最慢.

SAX解析在我的两个Android设备上都快了一个数量级,管理40个docs/sec单线程和65 +/sec多线程.

Android 2.3.4:

Android上xml解析方法的性能比较

代码在github中可用,并在此处进行讨论.

2016年3月18日更新

好吧,所以它已经差不多4年了,世界已经发展了.我终于开始重新运行测试了:

  1. 运行Android 4.1.2的三星Galaxy S3
  2. 运行Android 4.4.4的Nexus7(2012)
  3. 运行Android 6.0.1的Nexus5

在Android 4.4.4和Android 6.0.1之间,情况发生了巨大变化,我们有了一个新的赢家:拉动解析FTW的速度是SAX吞吐量的两倍多.不幸的是,由于我没有运行Android> 4.4.4和<6.0.1的任何设备,因此我不确切知道此更改的确切时间.

Android 4.1.2:

Android 4.1.2上xml解析方法的性能比较

Android 4.4.4:

Android 4.4.4上xml解析方法的性能比较

Android 6.0.1:

Android 6.0.1上xml解析方法的性能比较


Mak*_*lin 5

我认为在Android上使用XML的最佳方法是使用VDT-XML库

我的XML文件包含超过60 000行,VDT-XML处理如下:

Nexus 5:2055毫秒

Galaxy Note 4:2498 milisec

您可以通过链接找到更多基准报告:VTD-XML Benchmark

XML文件的简短示例

 <database name="products">
        <table name="category">
            <column name="catId">20</column>
            <column name="catName">Fruit</column>
        </table>
        <table name="category">
            <column name="catId">31</column>
            <column name="catName">Vegetables</column>
        </table>
        <table name="category">
            <column name="catId">45</column>
            <column name="catName">Rice</column>
        </table>
        <table name="category">
            <column name="catId">50</column>
            <column name="catName">Potatoes</column>
        </table>
</database>
Run Code Online (Sandbox Code Playgroud)

配置"build.gradle"文件

dependencies {
    compile files('libs/vtd-xml.jar')
}
Run Code Online (Sandbox Code Playgroud)

源代码示例:

import com.ximpleware.AutoPilot;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;


String fileName = "products.xml";

VTDGen vg = new VTDGen();

if (vg.parseFile(fileName, true)) {

     VTDNav vn = vg.getNav();
     AutoPilot table = new AutoPilot(vn);
     table.selectXPath("database/table");

     while (table.iterate()) {
        String tableName = vn.toString(vn.getAttrVal("name"));

        if (tableName.equals("category")) {
            AutoPilot column = new AutoPilot(vn);
            column.selectElement("column");

            while (column.iterate()) {
                 String text = vn.toNormalizedString(vn.getText());
                 String name = vn.toString(vn.getAttrVal("name"));

                 if (name.equals("catId")) {
                    Log.d("Category ID = " + text);
                 } else if (name.equals("catName")) {
                    Log.d("Category Name = " + text);
                 } 

            }
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

结果

Category ID = 20
Category Name = Fruit

Category ID = 31
Category Name = Vegetables

Category ID = 45
Category Name = Rice

Category ID = 50
Category Name = Potatoes
Run Code Online (Sandbox Code Playgroud)

它对我有用,希望它对你有所帮助.