gazay / gon

Your Rails variables in your JS
MIT License
3.05k stars 184 forks source link

Introduce keys cache #228

Closed vlazar closed 7 years ago

vlazar commented 7 years ago

With lots of data key.to_s and camelize(:lower) can be a bottleneck.

Probably Gon was never intended for such use case, but here we are... We have some pages with lots of data pushed to Gon, like ~1Mb JSON on some pages.

We've discovered that enormous amount of server response time was spent in Gon::Base.render_data. We use :snake_case hash keys in our code and let Gon to camelize them. Surprisingly enough most of time was the time spent in camelize(:lower) calls.

Believe it or not, but by introducing caching for camelized keys the mean response time went from 3700ms to 700ms. This is more than 5x improvement!. Memory consumption has also improved dramatically, because lots of String objects were allocated by key.to_s and camelize(:lower) calls. For our ~1Mb JSON this is like 50 unique key names and about 50K calls to camelize them over and over again.

I'm not sure if this is the right place to introduce keys cache in Gon, or should this be in RequestStore, but I'm happy to discuss other options.

I've also done some synthetic benchmarks for Gon::Base.render_data(camel_case: true, camel_depth: :recursive) with the following results: 5 objects with 5 keys: ~ 2.3x faster with cache 5000 objects with 5 keys: ~ 3.3x faster with cache

gazay commented 7 years ago

Whoa! That looks awesome :) Thank you!

vlazar commented 7 years ago

@gazay Wow, thank you, that was quick!