If you want to optimize for speed, I'd recommend using Nokogiri, but not the Nokogiri::XML::Builder which will perform about as well as the Builder gem. Instead, use the lower-level Document and Node APIs.

Here's some code showing equivalent document construction for Builder, Nokogiri::XML::Builder, and Nokogiri::XML::Document ... and a benchmark if it's helpful (higher numbers are better, it's iterations per second):

```ruby
#! /usr/bin/env ruby

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "builder"
  gem "nokogiri"
  gem "benchmark-ips"
end

require "builder"
require "nokogiri"
require "benchmark/ips"

N = 100

# using Builder::XmlMarkup, build an XML document representing attributes of a person
def builder_person
  xml = Builder::XmlMarkup.new
  xml.people do |p|
    N.times do
      xml.person do |p|
        p.name "John Doe"
        p.age 42
        p.address do |a|
          a.street "123 Main Street"
          a.city "Anytown"
        end
      end
    end
  end
end

# using Nokogiri::XML::Builder, build an XML document representing attributes of a person
def nokogiri_person
  Nokogiri::XML::Builder.new do |xml|
    xml.people do
      N.times do
        xml.person do |p|
          p.name "John Doe"
          p.age 42
          p.address do |a|
            a.street "123 Main Street"
            a.city "Anytown"
          end
        end
      end
    end
  end.to_xml
end

# use Nokogiri's bare API to build an XML document representing attributes of a person
def nokogiri_raw_person
  xml = Nokogiri::XML::Document.new
  xml.root = xml.create_element("people")
  N.times do
    xml.root.add_child(xml.create_element("person")).tap do |p|
      p.add_child(xml.create_element("name", "John Doe"))
      p.add_child(xml.create_element("age", 42))
      p.add_child(xml.create_element("address")).tap do |a|
        a.add_child(xml.create_element("street", "123 Main Street"))
        a.add_child(xml.create_element("city", "Anytown"))
      end
    end
  end
  xml.to_xml
end

puts RUBY_DESCRIPTION
# pp builder_person
# pp nokogiri_person
# pp nokogiri_raw_person

Benchmark.ips do |x|
  x.report("builder") { builder_person }
  x.report("nokogiri") { nokogiri_person }
  x.report("nokogiri raw") { nokogiri_raw_person }
  x.compare!
end
```

```
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
             builder    58.000  i/100ms
            nokogiri    49.000  i/100ms
        nokogiri raw    61.000  i/100ms
Calculating -------------------------------------
             builder    541.580  (± 6.5%) i/s -      2.726k in   5.054535s
            nokogiri    451.127  (± 7.5%) i/s -      2.254k in   5.027192s
        nokogiri raw    681.437  (± 9.1%) i/s -      3.416k in   5.061582s

Comparison:
        nokogiri raw:      681.4 i/s
             builder:      541.6 i/s - 1.26x  slower
            nokogiri:      451.1 i/s - 1.51x  slower
```

On Thu, May 18, 2023 at 8:02 AM Austin Ziegler via ruby-talk <ruby-talk@ml.ruby-lang.org> wrote:
I have never used the Rails builder interface for JSON or XML generation. It’s nice because it’s DSL-ish, but it needs to be executed.

If your data can be templated, using ERB will be better. If it is more complex with attributes, look into restructuring it so that you can use Nokogiri. I’m not sure if Ox generates as well as parses, but it may also be an option.

-a

> On May 18, 2023, at 04:25, Peter Hickman via ruby-talk <ruby-talk@ml.ruby-lang.org> wrote:
>
> 
> I'm profiling some code to try and squeeze out performance. It takes a user query, reads data from the database and returned the result as XML
>
> I have tuned the code and database (checking the indexes, caching repeated calls etc) and what I am left with is that 95% of the call's runtime is building the XML. We are using builder because it is the standard / default for Ruby
>
> Using Ruby 3.0.2p107 as it is the default for Ubuntu 22.04
>
> Is there another, faster library for XML generation or will I be building this by hand?
>
> Any suggestions
>
> ______________________________________________
> ruby-talk mailing list -- ruby-talk@ml.ruby-lang.org
> To unsubscribe send an email to ruby-talk-leave@ml.ruby-lang.org
> ruby-talk info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-talk.ml.ruby-lang.org/
 ______________________________________________
 ruby-talk mailing list -- ruby-talk@ml.ruby-lang.org
 To unsubscribe send an email to ruby-talk-leave@ml.ruby-lang.org
 ruby-talk info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-talk.ml.ruby-lang.org/