I maintain a website of events taking place in my city.
My website homepage is a 5-days calendar with all the events taking place from today to 4 days in the future.
I have done quite a good job with my "ActiveRecord" code as I have around ~120ms spent in MySQL (double checked with RackMiniProfiler) to load ~200-300 events.
However my response time is very slow (1.5s - 2s).
Most time is spent in instantiation of AR's objects from my queries
Using ObjectSpace, I see that ~6k AR::Base objects are instantiated for +300 events that are displayed.
The reason why there are so many objects is that my Event model has many associated models (e.g. venue, occurrences, categories, etc...), all of which contain bits of information I need to show.
As expected, profiling proved ActiveRecord's object instantiation as the most consuming task during the request.
I am not experienced enough in neither ActiveRecord nor its performance.
Is such speed expected or should my objects be instantiated much faster?
Should I move away from AR and use simple ruby hashes?
Is this the Rails standard when my data model is too complex?
========= UPDATE 1 =========
This pastebin contains the service class I use to load the events for a single day in the calendar. I hope it's understandable, I did not have time to properly document it since it's still a work in progress to improve performance.
========= UPDATE 2 =========
Loading all these objects has another drawback: it causes GC runs while the page is being rendered, adding ~100ms after every n events are rendered, which becomes a total overhead of ~500ms.
To give you an idea of how much data I'm loading (sadly 99% of it is needed), if I dump to JSON I get a 47K file.
========= UPDATE 3 =========
As mentioned by @TheSuper, even though it does not improve AR's performance, fragment caching is indeed my friend as I'm rendering quite the amount of data while under GC runs. Applying fragment caching yielded a 1-1.2s improvement, which is HUGE.
However I still cannot overcome the 600ms wall of AR. A possible improvement are "selective includes" discussed in this answer, for the few cases where I need a small portion of the attributes of an included model, but this is ugly and inflexible.