Мне нужно создать огромный XML-файл, около 1-50 МБ.Я думал, что использование компоновщика будет достаточно эффективным и, ну, в некоторой степени.Проблема в том, что после того, как программа достигает последней строки, она не заканчивается немедленно, но Ruby все еще что-то делает в течение нескольких секунд, может быть, сборщик мусора?После этого программа окончательно завершается.
Чтобы привести реальный пример, я измерил время создания файла XML.Он выводит 55 секунд (база данных отстает, так что это занимает много времени), когда XML был построен, но Ruby все еще обрабатывает еще около 15 секунд, и процессор сходит с ума.
Псевдо / реальный кодследует:
...
builder = Nokogiri::XML::Builder.with(doc) do |xml|
build_node(xml)
end
...
def build_node(xml)
...
xml["#{namespace}"] if namespace
xml.send("#{elem_name}", attrs_hash) do |elem_xml|
...
if has_children
if type
case type
when XML::TextContent::PLAIN
elem_xml.text text_content
when XML::TextContent::COMMENT
elem_xml.comment text_content
when XML::TextContent::CDATA
elem_xml.cdata text_content
end
else
build_node(elem_xml)
end
end
end
end
Обратите внимание, что я использовал другой подход, используя свою собственную структуру классов, и скорость сборки была такой же, но на последней строке программа обычно заканчивалась, но теперь яЯ вынужден использовать Nokogiri, поэтому мне нужно найти решение.
Что я могу сделать, чтобы избежать дополнительных X секунд после создания XML?Возможно ли это вообще?
ОБНОВЛЕНИЕ:
Благодаря предложению Адиэля Митманна, во время создания моего минимального рабочего примера я смог найти проблему.Теперь у меня есть небольшой (но не такой маленький) пример, демонстрирующий проблему.
Следующий код вызывает проблему:
xml.send("#{elem_name}_") do |elem_xml|
...
elem_xml.text text_content #This line is the problem
...
end
Таким образом, строка выполняет следующий код, основанный на документации Nokogiri.:
def create_text_node string, &block
Nokogiri::XML::Text.new string.to_s, self, &block
end
Затем выполняется код создания текстового узла .Итак, что именно здесь происходит?
ОБНОВЛЕНИЕ 2:
После некоторых других попыток проблема может быть легко воспроизведена с помощью:
builder = Nokogiri::XML::Builder.new do |xml|
0.upto(81900) do
xml.text "test"
end
end
puts "End"
Так это действительно Nokogiriсам?Есть ли вариант для меня?