Nokogiri :: XML::Builder получается медленнее, чем Builder для генерации XML в Rails?

#ruby-on-rails #ruby #xml #nokogiri

#ruby-on-rails #ruby #xml #nokogiri

Вопрос:

Некоторое время мы использовали Rails ‘(2.3.3) Builder для генерации XML-разметки для наших API, когда мы думали, что Nokogiri Builder будет генерировать XML быстрее (как многие указывали).

Проблема в том, что мои тесты показали, что Nokogiri::Builder медленнее, чем обычный Builder:

 Nokogiri::Builder: 3.1314s
Builder:           2.1592s
 

для рендеринга одного и того же запроса 10 раз. Я несколько раз повторял подобные тесты в разных средах, поэтому я уверен, что Nokogiri работает медленнее.

Наше приложение имеет множество представлений .xml.builder, которые используют многие части .xml.builder:

 xml.instruct!
xml.feed do
  xml.stuff do
    xml.more_stuff(...)
  end
  xml.location do
    xml << render(:partial => shared/location, :object => mylocation)
  end
end
 

В приведенном выше примере используется shared/_location.xml.builder . Наше приложение в значительной степени использует такие части XML для организации кода.

Я перешел на Nokogiri после «Ускорения ваших ответов Rails XML» (см. Приложение для тестирования там).

Мой обработчик шаблонов выглядит так:

 class NokogiriBuilder < ActionView::TemplateHandler
  include ActionView::TemplateHandlers::Compilable

  def compile template
    "_set_controller_content_type(Mime::XML);"  
      "xml = ::Nokogiri::XML::Builder.new(:encoding => 'UTF-8') { |xml| "  
      template.source  
      '}.to_xml; self.output_buffer = xml;'
  end 
end
 

Когда я попытался запустить свой код через rubyprof, результаты показывают, что create_element занимает много времени!

  %self     total     self     wait    child    calls  name
 23.47      1.15     1.15     0.00     0.00      731  Mysql#query
  9.59      0.78     0.47     0.00     0.31     1437  Nokogiri::XML::Document#create_element
  7.96      3.61     0.39     0.00     3.61      867  <Module::Benchmark>#realtime
  5.51      0.27     0.27     0.00     0.00     1167  Nokogiri::XML::Node#encode_special_chars
  5.51      0.28     0.27     0.00     0.01     1370  Module#define_method
  5.10      0.26     0.25     0.00     0.01      346  Array#select
  3.88      0.19     0.19     0.00     0.00     5236  Module#constants
  3.27      0.90     0.16     0.00     0.83     1820  Array#collect
  2.45      0.13     0.12     0.00     0.01     1712  Rack::Lint::Assertion#assert
  2.24      1.09     0.11     0.00     1.09      554  ActiveSupport::CoreExtensions::String::Inflections#constantize
  2.04      0.10     0.10     0.00     0.00       23  Nokogiri::XML::ParseOptions#initialize
  2.04      0.10     0.10     0.00     0.00      726  <Class::ActiveSupport::Callbacks::CallbackChain>#extract_options
 

Мне действительно интересно, что такого особенного в моем случае, что Nokogiri будет работать медленнее, хотя для многих людей это оказалось во много раз быстрее!

Никаких нежных занятий любовью? 🙁

Комментарии:

1. 1 для подробной информации и профилирования, но -1 для… в чем вопрос? Почему одна библиотека немного медленнее другой для вашего конкретного варианта использования, когда какая-то запись в блоге заставила вас думать, что она всегда будет быстрее в любом случае?

2. Это в некотором роде верно, поскольку этот , этот и другие упоминали о больших улучшениях. Поскольку я сейчас оптимизирую свое приложение, это казалось легким выигрышем. Вопрос в том, что конкретно может быть в моем приложении, чтобы замедлить работу более быстрой библиотеки? То, что я делаю, может быть чем-то очень неправильным.

3. Важно проверять даты блогов, когда вы рассчитываете на их информацию. Первый был написан за два года до публикации этого вопроса, и за это время Rails претерпели бы множество обновлений, так что легко понять, почему результаты могли быть другими. Интернет никогда не забывает, но информация действительно устаревает.

4. Согласен с приведенными выше комментариями. Существует, возможно, дюжина факторов, которые могут повлиять на производительность, не связанных с синтаксическим анализом XML. Например, если вы используете версию Rails от 2009 года, используете ли вы также и старую версию ruby? Какая ОС? Вы читаете большие файлы с медленного диска? Nokogiri, вероятно, быстрее разбирается, когда XML находится в памяти, но получение его там и готовность (даже внутри Nokogiri) могут сильно различаться. Кроме того, размер и сложность анализируемого объекта имеют значение — например, мы читаем более 100 мегабайтных XML-файлов, и Nokogiri в этом случае работает быстрее.