5 ms·
I may be wrong, but aren't you doing two loops by doing it that way? One for the select, and another for the map? Or does ruby compile out the select loop with
by howeyc 4y ago
I may be wrong, but aren't you doing two loops by doing it that way? One for the select, and another for the map? Or does ruby compile out the select loop with smarts.
In Go, the intuitive way would be one loop with an if inside it. So it would be easy to spot this performance issue if you did it the ruby way with two loops.
https://go.dev/play/p/ixDKuosxPNp https://go.dev/play/p/ixDKuosxPNp
I bet I wrote my for loop as quickly as you wrote your map. The character count isn't that much higher.
- kaba0 4y agoNot sure about Ruby, but Java’s streams would do one loop only here, as they are lazy. Also, both solutions are O(n), so unless this is the hot loop of your program, or it iterates over some insane amount of entities, it is a completely meaningless microoptimization.
- bin_bash 4y agoThe amount of times in my career where the performance would be even measurable between these 2 styles is vanishingly few. If I cared I could just use #filter_map or a classic for-each loop. If we're assuming the project is written in Ruby in the first place, clearly we're not valuing performance that highly. The more important thing is the ruby version is chainable and more readable—and that matters far more often.
- gkop 4y agoYou had me until > more readable Without having more context, User in your code is possibly an ActiveRecord class, so to read the #select, you have to consider that it could be radically different and heavier than Enumerable#select (eg. it may execute a DB query as a side effect). So I like your example still, because it’s representative, and certainly expressive, but not readable per se. IMO this sin here is simply that ActiveRecord shouldn’t have overloaded select.
- bin_bash 4y agoThat’s more of an argument against ORMs which I realize my example used. I was mostly trying to convey using map/filter against POROs though. Using an ORM was a poor choice on my part. I agree the magic there does harm readability since it makes it a lot harder to understand what it really is doing.
- Lio 4y agoRuby has had lazy iteration[1] for quite a while but as n here is only 10 there's really not much to loose in not using it. In fact given that only a subset of users will be admin users for the second loop n is going to < 10 anyway. I believe it was Rob Pike that actually said something along the lines of not bothering to optimise until you know that n is large[2]. 1. https://ruby-doc.org/core-2.5.0/Enumerator/Lazy.html https://ruby-doc.org/core-2.5.0/Enumerator/Lazy.html 2. https://users.ece.utexas.edu/~adnan/pike.html https://users.ece.utexas.edu/~adnan/pike.html