在ruby中创建大文件xml

前端之家收集整理的这篇文章主要介绍了在ruby中创建大文件xml前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想把一些数据写入 XML文件( XML文件会到〜50 MB).

我发现nokogiri(1.5.0)宝石是最有效的解析(只读和不写). Nokogiri不是写入XML文件的好选择,因为它在内存中保存完整的XML数据,直到写入最后写入它.

我发现builder(3.0.0)是一个很好的选择,但不知道它是否是最佳选择.

我使用以下简单代码尝试了一些基准测试:

  1. (1..500000).each do |k|
  2. xml.products {
  3. xml.widget {
  4. xml.id_ k
  5. xml.name "Awesome widget"
  6. }
  7. }
  8. end

Nokogiri需要大约143秒钟,内存消耗逐渐增加,最终达到约700 MB.

Builder耗时约123秒,内存消耗稳定在10 MB.

那么在Ruby中编写巨大的XML文件(50 MB)有更好的解决方案?

Nokogiri文件

  1. require 'rubygems'
  2. require 'nokogiri'
  3. a = Time.now
  4. builder = Nokogiri::XML::Builder.new do |xml|
  5. xml.root {
  6. (1..500000).each do |k|
  7. xml.products {
  8. xml.widget {
  9. xml.id_ k
  10. xml.name "Awesome widget"
  11. }
  12. }
  13. end
  14. }
  15. end
  16. o = File.new("test_noko.xml","w")
  17. o.write(builder.to_xml)
  18. o.close
  19. puts (Time.now-a).to_s

生成文件

  1. require 'rubygems'
  2. require 'builder'
  3. a = Time.now
  4. File.open("test.xml",'w') {|f|
  5. xml = Builder::XmlMarkup.new(:target => f,:indent => 1)
  6.  
  7. (1..500000).each do |k|
  8. xml.products {
  9. xml.widget {
  10. xml.id_ k
  11. xml.name "Awesome widget"
  12. }
  13. }
  14. end
  15.  
  16. }
  17. puts (Time.now-a).to_s

解决方法

解决方案1

如果速度是您的主要关注点,我只需直接使用libxml-ruby(http://libxml.rubyforge.org/rdoc/):

  1. $time ruby test.rb
  2.  
  3. real 0m7.352s
  4. user 0m5.867s
  5. sys 0m0.921s

api很直接

  1. require 'rubygems'
  2. require 'xml'
  3. doc = XML::Document.new()
  4. doc.root = XML::Node.new('root_node')
  5. root = doc.root
  6.  
  7. 500000.times do |k|
  8. root << elem1 = XML::Node.new('products')
  9. elem1 << elem2 = XML::Node.new('widget')
  10. elem2['id'] = k.to_s
  11. elem2['name'] = 'Awesome widget'
  12. end
  13.  
  14. doc.save('foo.xml',:indent => false,:encoding => XML::Encoding::UTF_8)

使用:indent =>在这种情况下,true并没有太多的区别,但是对于更复杂的xml文件,它可能会做.

$time ruby​​ test.rb#(带缩进)

  1. real 0m7.395s
  2. user 0m6.050s
  3. sys 0m0.847s

解决方案2

当然最快的解决方案,而不是建立在内存上只是为了手动编写xml,但是很容易产生错误的其他来源,例如可能是无效的xml.

  1. $time ruby test.rb
  2.  
  3. real 0m1.131s
  4. user 0m0.873s
  5. sys 0m0.126s

这里是代码

  1. f = File.open("foo.xml","w")
  2. f.puts('<doc>')
  3. 500000.times do |k|
  4. f.puts "<product><widget id=\"#{k}\" name=\"Awesome widget\" /></product>"
  5. end
  6. f.puts('</doc>')
  7. f.close

猜你在找的Ruby相关文章