With any Ruby code under load, it's important to have a proper understanding of what's happening in memory -- if adding memoisation is yielding significant gains, there's likely much more potential for optimisation
Many in the Ruby community have taken a 1974 quote from Donald Knuth out of context and used it as a justification for minimal or zero effort on memory efficiency
The article is a very interesting read, but implementation is heavily reliant on metaprogramming magic that can be something of a grenade in realworld projects especially if anyone fairly new to Ruby has to fix it later
Almost none of the gems I used 10 years ago still exist today -- taking a small penalty for hand-rolling initially will usually save days or more later -- the author even says a similar earlier Gem he built is long gone
> if adding memoization is yielding significant gains, there's likely much more potential for optimization
Most often when I see memoization in Ruby code it is when fetching data from either a db or external service. Memory isn't the concern is these cases.
> Almost none of the gems I used 10 years ago still exist today -- taking a small penalty for hand-rolling initially will usually save days or more later -- the author even says a similar earlier Gem he built is long gone
With a clean DSL changing the gem or removing it for your own solution should not be problem.
If app is repeatedly asking DB for same data and it's immutable for a period -- the persistance choice is wrong
There is potentially a whole lot of memory/callstack overhead involved in a request like that even when memoised
It likely should be in a memory structure all the time or Redis if sufficiently complex / shared across processes etc. as all the other processes will likely be doing same
Only in Ruby world would someone say yeah what we need right there is a Gem with some define_method sprinkles
> If app is repeatedly asking DB for same data and it's immutable for a period -- the persistance choice is wrong
Says who? ACID databases are the norm for a reason.
> There is potentially a whole lot of memory/callstack overhead involved in a request like that even when memoised
So because there is overhead elsewhere you shouldn't optimize here?
> It likely should be in a memory structure all the time or Redis if sufficiently complex / shared across processes etc. as all the other processes will likely be doing same
Redis doesn't help if the issue is the network io. Accessing anything out of process memory will objectively be slower than accessing in process memory. Doesn't matter if the data is coming from pg, redis, or wherever. If its going across the wire, there will be io latency.
> Only in Ruby world would someone say yeah what we need right there is a Gem with some define_method sprinkles
Ah, I see this is based on a negative view of ruby in particular. Memoization is a common pattern in basically every language, and can net significant performance wins with very little effort (low hanging fruit). Is it a magic bullet? Nope. But it's nice to have in the tool belt when dealing with an app that's falling on its face and every improvment means you get to sleep better at night.
> Only in Ruby world would someone say yeah what we need right there is a Gem with some define_method sprinkles
Oh sorry. I didn't mean for it to sound like that is what I was saying.
What I meant was a gem with a memoization DSL shouldn't be hard to remove if you decide you no longer want it, so I do not think it is a great reason to not go with a gem it it solves your need.
To be clear, in 18 years of Ruby I've never work on a project that used a gem for this sort of thing. That being said–I think a better interface for memoization would make it easier to reach for the right tool at the right time. And I've work large enough project where even a project specific DSL in lib would be valuable across the project.
The thing about metaprogramming magic in Ruby is that, it can work okay for one thing, but if you have 2 or 3 or more things all using it to do different things, it's very likely they'll conflict and blow up in a way that's really difficult to troubleshoot or solve.
Many in the Ruby community have taken a 1974 quote from Donald Knuth out of context and used it as a justification for minimal or zero effort on memory efficiency
The article is a very interesting read, but implementation is heavily reliant on metaprogramming magic that can be something of a grenade in realworld projects especially if anyone fairly new to Ruby has to fix it later
Almost none of the gems I used 10 years ago still exist today -- taking a small penalty for hand-rolling initially will usually save days or more later -- the author even says a similar earlier Gem he built is long gone