trailblazer / roar

Parse and render REST API documents using representers.
http://www.trailblazer.to/gems/roar
MIT License
1.85k stars 138 forks source link

Hypermedia feature slow due to OpenStruct #88

Open dtshepherd opened 10 years ago

dtshepherd commented 10 years ago

I've been having issues with hypermedia performance when returning a large collection that has hypermedia in each item. Running ruby prof, I found most time is spent in hypermedia link generation, specifically the OpenStruct creations. Doing some research, it looks like this is a know issue: http://stackoverflow.com/questions/1177594/ruby-struct-vs-openstruct

It can be 100x slower than just using hashes and are memory hogs. Trying to think of a good way to replace this and keep hypermedia...

Short term hack would be to do inline collection, manually define a getter method for each link, and mark each read-only. There has to be a better way though.

apotonick commented 10 years ago

I saw a gem called fast-openstruct or something - what if we'd use that? If you have benchmarks ready, we can try and push it today.

dtshepherd commented 10 years ago

I'll try that gem out. Super busy in my day job, so may not get to it until the weekend.

On Wed, Jan 29, 2014 at 4:14 PM, Nick Sutterer notifications@github.comwrote:

I saw a gem called fast-openstruct or something - what if we'd use that? If you have benchmarks ready, we can try and push it today.

Reply to this email directly or view it on GitHubhttps://github.com/apotonick/roar/issues/88#issuecomment-33631402 .

dtshepherd commented 10 years ago

FastOpenStruct is not a drop in replacement for OpenStruct. It doesn't properly support inheritance, which is the way it is used inside Hypermedia. I hacked it in quick and dirty, and ruby prof CallTree is showing more time is being spent in Module.name via Representable#representation_wrap call. Not sure why, because with normal OpenStruct, I'm not seeing that...

On Wed, Jan 29, 2014 at 5:52 PM, David Shepherd dtshepherd@gmail.comwrote:

I'll try that gem out. Super busy in my day job, so may not get to it until the weekend.

On Wed, Jan 29, 2014 at 4:14 PM, Nick Sutterer notifications@github.comwrote:

I saw a gem called fast-openstruct or something - what if we'd use that? If you have benchmarks ready, we can try and push it today.

Reply to this email directly or view it on GitHubhttps://github.com/apotonick/roar/issues/88#issuecomment-33631402 .

apotonick commented 10 years ago

You know what would help? A rails app setup with profiling. I'm thinking about just using a self-made OpenStruct.

dtshepherd commented 10 years ago

Agreed, I'm not very helpful here am I? :)

That was my other thought, just write your own OpenStruct for this purpose. I think hypermedia is the most time consuming in my app right now. ~20% time for the rails url helpers and 80% for the OpenStruct on the fly hypermedia creation.

However, this performance hit was only realized after I switched to decorators.  The extend method killed performance for large queries (>500 items returned).  I went from 100 seconds for a 1000 item query to just under 3 seconds. While to_json for standard rails (no roar) took ~3 seconds as well.

Performance tuning sucks...

On Thu, Feb 6, 2014 at 11:24 PM, Nick Sutterer notifications@github.com wrote:

You know what would help? A rails app setup with profiling. I'm thinking about just using a self-made OpenStruct.

Reply to this email directly or view it on GitHub: https://github.com/apotonick/roar/issues/88#issuecomment-34403210

apotonick commented 10 years ago

But this should be an easy win - so we need a simple setup with like 500 items, each with hyperlinks? We don't even need a database for that, neither Rails.

dtshepherd commented 10 years ago

Yep, let me see if I can rig a test like that. Make sure it reproduces the problem.

On Thu, Feb 6, 2014 at 11:43 PM, Nick Sutterer notifications@github.com wrote:

But this should be an easy win - so we need a simple setup with like 500 items, each with hyperlinks? We don't even need a database for that, neither Rails.

Reply to this email directly or view it on GitHub: https://github.com/apotonick/roar/issues/88#issuecomment-34403860

mattsnyder commented 10 years ago

What became of this? Noticing performance problems myself on larger collections

apotonick commented 10 years ago

Nothing, yet, because I can't do 5 million things at the same time. :dancer:

I doubt that the performance is because of an OpenStruct. Have you tried representable 2.1? It's got about 30-40% speedup by simply removing Ruby's delegator and method_missing.