使用 Ruby on Rails (1.4GB) 解析非常大的 XML 文件 -- 有没有比 SAXParser 更好的方法?
目前,我正在使用 LIBXML::SAXParser::Callbacks 来解析包含 140,000 个产品数据的大型 XML 文件。我正在使用一项任务将这些产品的数据导入到我的 Rails 应用程序中。
我的最后一次导入只用了不到 10 个小时就完成了:
rake asi:import_products --trace 26815.23s user 1393.03s system 80% cpu 9:47:34.09 total
当前实现的问题是 XML 中复杂的依赖结构意味着我需要跟踪整个产品节点才能知道如何正确解析它。
理想情况下,我想要一种可以单独处理每个产品节点并能够使用 XPATH 的方法,文件大小限制我们使用需要将整个 XML 文件加载到内存中的方法。我无法控制原始 XML 的格式或大小。我最多可以在该进程中使用 3GB 的内存。
还有比这更好的方法吗?
Currently, I'm using LIBXML::SAXParser::Callbacks to parse a large XML file containing data 140,000 products. I'm using a task to import the data for these products into my rails app.
My last import took just under 10 hours to complete:
rake asi:import_products --trace 26815.23s user 1393.03s system 80% cpu 9:47:34.09 total
The problem with the current implementation is that the complex dependency structure in the XML means, I need to keep track of the entire product node to know how to parse it properly.
Ideally, I'd like a way that I could process each product node by itself and have the ability to use XPATH, the file size restricts us from using a method that requires loading the entire XML file into memory. I cannot control the format or size of original XML. I have at most, 3GB worth of memory I can use on the process.
Is there a better way than this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你能先获取整个文件吗?如果是这样,那么我建议将 XML 文件分割成较小的块(例如 512MB 左右),以便您可以一次解析同时的块(每个核心一个),因为我相信您拥有现代 CPU。关于无效或格式错误的 xml - 只需通过简单的字符串操作附加或添加缺失的 XML。
您还可以尝试分析您的回调方法。这是一大块代码,我很确定应该至少有一个瓶颈可以节省您几分钟的时间。
Can you fetch whole file first? If so, then I'd suggest splitting an XML file into smaller chunks (say, 512MBs or so) so you could parse simultaneous chunks at one time (one per core), 'cause I believe you have modern CPU. Regarding the invalid or malformed xml - just append or prepend missing XML with simple string manipulation.
You can also try profiling your callback method. It's a big chunk of code, I'm pretty sure there should be at least one bottle neck which could save you a few minutes.