gpt4 book ai didi

ruby-on-rails - 从一堆模型对象生成 XML 时速度较慢

转载 作者:数据小太阳 更新时间:2023-10-29 01:51:33 25 4
gpt4 key购买 nike

class GenericFormatter < Formatter
attr_accessor :tag_name,:objects

def generate_xml
builder = Nokogiri::XML::Builder.new do |xml|
xml.send(tag_name.pluralize) {
objects.each do |obj|
xml.send(tag_name.singularize){

self.generate_obj_row obj,xml
}
end
}
end
builder.to_xml
end


def initialize tag_name,objects
self.tag_name = tag_name
self.objects = objects
end


def generate_obj_row obj,xml
obj.attributes.except("updated_at").map do |key,value|
xml.send(key, value)
end
xml.updated_at obj.updated_at.try(:strftime,"%m/%d/%Y %H:%M:%S") if obj.attributes.key?('updated_at')
end
end

在上面的代码中,我已经实现了格式化程序,我使用 nokogiri XML Builder 通过操作代码内部传递的对象来生成 XML。如果数据不是太大,它会生成更快的 XML如果超过 10,000 条记录,那么它会减慢 XML 的生成速度,并且至少需要 50-60 秒。

问题: 有什么方法可以更快地生成 XML,我也尝试过查看 XML Builders,但没有用。如何更快地生成 XML?解决方案是否应该是 Rails 3 上的应用程序以及优化上述代码的建议?

最佳答案

您的主要问题是一次处理所有内容,而不是将数据分成几批。这一切都需要大量内存,首先构建所有那些 ActiveRecord 模型,然后构建整个 xml 文档的内存表示。元编程也相当昂贵(我指的是那些 send 方法)。

看看这段代码:

class XmlGenerator
attr_accessor :tag_name, :ar_relation

def initialize(tag_name, ar_relation)
@ar_relation = ar_relation
@tag_name = tag_name
end

def generate_xml
singular_tag_name = tag_name.singularize
plural_tag_name = tag_name.pluralize

xml = ""
xml << "<#{plural_tag_name}>"

ar_relation.find_in_batches(batch_size: 1000) do |batch|
batch.each do |obj|
xml << "<#{singular_tag_name}>"

obj.attributes.except("updated_at").each do |key, value|
xml << "<#{key}>#{value}</#{key}>"
end

if obj.attributes.key?("updated_at")
xml << "<updated_at>#{obj.updated_at.strftime('%m/%d/%Y %H:%M:%S')}</updated_at>"
end

xml << "</#{singular_tag_name}>"
end
end

xml << "</#{tag_name.pluralize}>"
xml
end
end

# example usage
XmlGenerator.new("user", User.where("age < 21")).generate_xml

主要改进是:

  • 批量从数据库中获取数据,需要传递ActiveRecord集合而不是ActiveRecord模型数组
  • 通过构造字符串生成xml,这有产生无效xml的风险,但比使用构建器快得多

我在超过 6 万条记录上对其进行了测试。生成这样的 xml 文档大约需要 40 秒。

还有很多工作可以进一步改进,但这完全取决于您的应用。

这里有一些想法:

  • 不要使用 ActiveRecord 获取数据,而是使用更轻的库或普通数据库驱动程序
  • 只获取您需要的数据
  • 调整批量大小
  • 将生成的 xml 直接写入文件(如果这是您的用例)以节省内存

关于ruby-on-rails - 从一堆模型对象生成 XML 时速度较慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44818546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com