Switch .count to .size where appropriate#1605
Conversation
|
There's a But many controllers may call this partial, and hmmm.... where to add the |
| best_count = -1 | ||
| names.each do |name| | ||
| count = name.observations.count | ||
| count = name.observations.length |
There was a problem hiding this comment.
I don't know if length is right; I don't know whether this is right. (I don't how where it gets used in user workflow.)
Maybe use size here and in other places? Is that bad form?
There was a problem hiding this comment.
@JoeCohen I don't know either, but I can answer one part of it. According to internet, size is an alias of length. (on Medium)(on Ruby in Rails).
There was a problem hiding this comment.
Update: Sorry, size is NOT an alias of length. Thank you Stack Overflow!
There was a problem hiding this comment.
However, that's an old answer. In the console, I notice that length on an association that has already been fetched only counts the number of cached records, so that may have changed.
There was a problem hiding this comment.
After reading through that whole thread, i think I should go with size. Thanks for figuring that out.
There was a problem hiding this comment.
You made me look.
If we need the records, length is better.
Else size is better.
length(). Link
Returns the size of the collection calling size on the target. If the collection has been already loaded, length and size are equivalent. If not and you are going to need the records anyway this method will take one less query. Otherwise size is more efficient.
So it looks like size is faster here. But I don't know if it's faster enough to be worth worrying about.
There was a problem hiding this comment.
From Roy Lindauer
count on a collection will always execute a COUNT() SQL statement to get an accurate count value. size returns the size of the collection, but will execute a COUNT() SQL statement if it's not already loaded. length returns the size of the collection from memory. If the collection has already been loaded and is in memory length and size are equivalent.
Relying on what's in memory may give you inaccurate results as the database could be modified while you are working on that collection. But making a bunch of expensive database calls to get an accurate count is probably something you want to avoid. There may be times when a count is preferred, but when in doubt it's probably better to use length.
also see diagrams here: https://www.akshaykhot.com/rails-length-size-count-difference/
I'm going to post all this stuff in a GitHub Discussion for reference.
| filter = ContentFilter.find(pref) | ||
| @user.content_filter[pref] = | ||
| if filter.type == :boolean && filter.prefs_vals.count == 1 | ||
| if filter.type == :boolean && filter.prefs_vals.length == 1 |
There was a problem hiding this comment.
Though it's not the point of this PR, can you use
one?
instead of
length == 1
There was a problem hiding this comment.
Yes! I don't know that method. Will alter
| paginator.num_total = ids.count | ||
| paginator.num_total = ids.length | ||
| ids[paginator.from..paginator.to] || [] | ||
| end |
There was a problem hiding this comment.
@pellaea is this OK in Query::HighLevelQueries? At the point of figuring out the paginator and the @num_results, the query is done, so it seems length is more appropriate.
It may make no difference currently, but it will probably matter if Query starts using scopes.
There was a problem hiding this comment.
Ok i now think size may be more appropriate.
There was a problem hiding this comment.
Oh dear god! I can't possibly read that entire email thread right now!
I do want to make sure one thing is pointed out in this one case, though -- ids here is not a query, it's just a plain old Array. So there's no question of it executing SQL queries or anything if "done wrong".
(Is there in fact any difference between size, count and length on a plain old Array??... oh hold on, strike that question... it's almost certainly answered somewhere in the email thread I just deleted! :)
Switch to `size`
Switch to `one?`
| return if @back_object | ||
|
|
||
| @back_object = if @collection_number.observations.count == 1 | ||
| @back_object = if @collection_number.observations.length == 1 |
There was a problem hiding this comment.
Another place for one?, which is defined as
# File activerecord/lib/active_record/relation.rb, line 282
def one?
return super if block_given?
limit_value ? records.one? : size == 1
endNote: I'm fine with not using one? here and elsewhere. I'm just putting it out as an option.
There was a problem hiding this comment.
Oops. Probably no on size, stick with length, as observations is used on the next line.
There was a problem hiding this comment.
OK. I went with one? - If you get a chance please have another look over everything — i've changed everything in the PR — and check if it seems right.
switch to `one?`
Switch to `size`
Switch to `size`
Switch to `size`
Switch to `size`
Switch to `one?`
.count to .length where appropriate.count to .size where appropriate
Switch to `size`
|
Thank you. A nice, succinct explanation of the differences, plus a link to
a very useful flow chart.
…On Sun, Sep 10, 2023 at 7:23 PM andrew nimmo ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In app/classes/suggestion.rb
<#1605 (comment)>
:
> @@ -68,7 +68,7 @@ def name_with_most_observations(names)
best_name = nil
best_count = -1
names.each do |name|
- count = name.observations.count
+ count = name.observations.length
From Roy Lindauer
<https://www.roylindauer.com/blog/the-difference-between-length-size-and-count-in-ruby-on-rails.html>
count on a collection will always execute a COUNT(*) SQL statement to get
an accurate count value. size returns the size of the collection, but will
execute a COUNT(*) SQL statement if it's not already loaded. length
returns the size of the collection from memory. If the collection has
already been loaded and is in memory length and size are equivalent.
Relying on what's in memory may give you inaccurate results as the
database could be modified while you are working on that collection. But
making a bunch of expensive database calls to get an accurate count is
probably something you want to avoid. There may be times when a count is
preferred, but when in doubt it's probably better to use length.
also see diagrams here:
https://www.akshaykhot.com/rails-length-size-count-difference/
I'm going to post all this stuff in a GitHub Discussion for reference.
—
Reply to this email directly, view it on GitHub
<#1605 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAALDFHTHQZY7YY4ICBVHCTXZZYZVANCNFSM6AAAAAA4SND3XQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***
com>
|
|
I'm out of time and probably won't be able to return to this PR. |
Should resolve a number of mysterious n+1's.
Discussion in #1598, starting here
Please check the changes thoroughly, especially to classes and the model.