views:

161

answers:

1

I'm trying to render a large (ish) array of objects as a plist in Ruby on Rails. The collection currently contains up to 200 objects, each of which is essentially a record (dictionary of keys/values). The overall result format is a plist (as used by Apple) but logically it is not much different from any XML document.

The problem I've hit is rendering the array takes about a second with 200 objects, which seems incredibly slow to me. I'm currently using code like this:

  def plistify(collection)
    resultarray=Array.new()
    collection.each do |entry|
      hash= entry.attributes
      hash["credits"]= entry.credits
      hash["ratingcount"]= entry.ratings.count
      hash["entryrating"]= entry.detail_rating
      hash["entryratingcount"]= entry.entryratingcount
      resultarray << hash
    end
    {'entries'=>resultarray}.to_plist
  end

Which is then sent to the client using:

format.text {render :text => plistify(@entries)}

The resulting output looks something like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
    <key>entries</key>
    <array> <-- corresponds to resultarray above
     <dict> <-- corresponds to a single entry's attributes above. one of these per entry.
      <key>cached_review_id</key>
      <integer>190</integer>
      <key>cached_tag_list</key>
      <string>pub restaurant food waitress</string>
      <key>created_at</key>
      <date>2009-05-31T13:47:10Z</date>
                    ...about 20 key/values...

etc. Almost all the overhead is in the ruby 'plistify' code - the database overhead is minimal by comparison.

Assuming the overhead might be from creating lots of temporary ruby objects, I've tried replacing all this with a view, and using a Builder in the view to create the same XML document - it works but is actually twice as slow!

Any ideas for how to improve on this, or otherwise identify the bottleneck?

+1  A: 

Not sure if there is much you can do to improve this without hacking about in the plist gem itself. Taking a look at the source code from the repository here "svn checkout http://plist.rubyforge.org/svn/" and here it looks like the gem is generating the XML all on its own as opposed to using an XML library (like LibXML, Nokogiri or builder).

I am not sure how much of a difference using one of these libraries will make in generating the XML (they are definitely faster at parsing) for you but it seems to be the first logical place to look for optimization opportunities.

Peer Allan