Hacker News new | ask | show | jobs
by joshmn 1154 days ago
I think the problem is a little more subtle.

With Rails, you can call `relation.map(&:id)` and `relation.pluck(:id)` and get the same thing — an array of `id`. But using map is 50x slower because it loads the entire model into memory (ActiveModel is very expensive) before enumerating; pluck fires a query and hits the result set from ActiveRecord — very inexpensive!

Average ability participants then fall for this foot gun (and others like it) and end up designing things poorly. One overlook quickly turns into accelerant at scale. This isn't unique to Rails, but Ruby — the delight that it is — makes it almost too trivial to do.

I've seen this happen at Rails shops many of us have an account on, where I wouldn't consider the people I worked with average ability participants either.

2 comments

But if you’re going to render those `relation` records in a paginated list anyway, pulling them into memory is superior so you don’t hit another DB round trip delay.

Which is to say, there’s a lot of ways to do things, and trade offs between the different ways, but isn’t that the case with any library or framework?

> But if you’re going to render

Sure – if – that's fine and optimal! In larger apps, where there's more complexity, there are so many paths that aren't that trivial and that's where the trouble begins.

I dont understand how come a framework will help you avoid that.

You can do a similar performance issue with anything: here is a raw example: give to anyone a non-ORM framework and the chances of someone hitting multiple times the DB to query the same records increases with team size and app scope. I am not sure there is a framework that can protect your colleagues from doing select * and then count the in memory objects instead of doing a count on DB.