3

我一直在为 iOS 和 Android 开发一个相当简单的应用程序,它解析本地 xml 以形成项目列表并显示有关它们的信息。在查看我的解析选项时,我选择了适用于 android 的本机 SAX 解析器,以及内置于 Objective-C 的 NSXMLparser 类。在查看我的选项时,我反复看到有人说 DOM 解析器不适合大型 xml 文件。然而,没有人确切地定义过“大”的含义。在应用程序的更高版本中,我正在考虑切换到 DOM 解析器。

我的问题是:您在哪里划清界限,并消除 DOM 解析器作为选项?有问题的平台是 iOS 和 Android,当然,这两个平台仍然有许多旧设备。那么,假设一个比平均速度慢的设备,线在哪里绘制?

谢谢您的考虑。

4

2 回答 2

8

DOM 解析器必须将整个 XML 加载到内存中。此外,与原始 XML 的大小相比,解析后的 XML 占用的内存通常是 5 到 10 倍。

如果您知道您的应用程序允许的内存消耗是 N 兆字节的 RAM,那么您可以自己画这条线:将 N 除以 10。

例如,如果您不想超过 10MB 的 RAM,那么您的 XML 不应超过 1MB。

只有最新的设备有 1GB 的 RAM(在所有应用程序中分配),旧设备有 512MB 甚至 256MB。256MB/10 = 25MB。您可能不想占用所有内存的 10% 以上,因此对于所有平台支持的 DOM XML,超过 2.5MB 的内存就太多了。

但是,这只是经验法则,只有现实生活中的测试才能告诉你真相。

于 2013-01-14T23:11:05.183 回答
1

什么太大了?这是您拥有多少工作记忆的函数,这会因设备而异。在 iPhone 上,在 3GS 上,你只有 256MB,iPhone 4 有 512MB,iPhone 5 有 1GB。

顺便说一句,whileNSXMLParser是一个 SAX 解析器,如果您使用initWithContentsOfURL,它会在解析开始之前将整个提要加载到内存中。因此,您会遭受类似 DOM 的大量内存消耗,但会使用繁琐的类似 SAX 的接口。因此,如果您查看 Apple 的PerformanceXML 示例,当他们说明一个占用空间小的流式 SAX 解析器时,他们会退回到LibXML2流式传输很好的示例。使用 时NSXMLParser,我还通过将 my 包装NSURLConnection在 a 中来实现类似的效果NSInputStream,因此我可以使用 SAX 解析器启用的小内存占用来调用initWithStream和享受。NSXMLParser

简而言之,在解析非常大的 XML 文件时,请确保您的 SAX 解析器不会仍然过度消耗内存,而是LibXML2使用NSXMLParser.NSInputStream

对我来说,这完全是任意的,如果 XML 超过 1MB,我将使用流式 SAX 解析器LibXML2。如果它那么大,我不会使用 DOM 解析器,也不会使用NSXMLParser.

另请参阅 Ray Wenderlich 的如何为您的 iPhone 项目选择最佳 XML 解析器

于 2013-01-14T23:49:27.820 回答