Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compare Array#drop with Array#[] #181

Closed

Conversation

parkerfinch
Copy link
Contributor

Endless ranges were introduced in Ruby 2.6, and are mentioned as a way
to idiomatically slice arrays.

(https://ruby-doc.org/core-2.6/Range.html#class-Range-label-Endless+Ranges)

This is slower than using Enumerable#drop.

Endless ranges were introduced in Ruby 2.6, and are mentioned as a way
to idiomatically slice arrays.

(https://ruby-doc.org/core-2.6/Range.html#class-Range-label-Endless+Ranges)

This is slower than using `Enumerable#drop`.
@marcandre
Copy link

It is not, and it shouldn't be (otherwise it would be a bug and we'd optimize MRI). Move the range creation out of your block and you will get similar results.

@mblumtritt
Copy link

FYI: Array#drop overrides Enumerable#drop (see array.c) , so you compare Array#[] with Array#drop

@parkerfinch
Copy link
Contributor Author

It is not, and it shouldn't be (otherwise it would be a bug and we'd optimize MRI). Move the range creation out of your block and you will get similar results.

Thanks @marcandre! That makes a whole lot of sense, I hadn't considered that we're really doing two operations with the range creation and the array slicing. Just so we have the data, I confirmed that if the range construction happens elsewhere then the results of #drop and #[] are similar:

Warming up --------------------------------------
          Array#drop   824.845k i/100ms
            Array#[]   868.100k i/100ms
Array#[] and make range
                       530.367k i/100ms
Calculating -------------------------------------
          Array#drop      8.579M (± 2.3%) i/s -     42.892M in   5.002207s
            Array#[]      8.754M (± 1.9%) i/s -     44.273M in   5.059723s
Array#[] and make range
                          5.545M (± 1.3%) i/s -     28.109M in   5.069981s

Comparison:
            Array#[]:  8753503.1 i/s
          Array#drop:  8579448.9 i/s - same-ish: difference falls within error
Array#[] and make range:  5545248.3 i/s - 1.58x  (± 0.00) slower

I'm still not sure how to go about this one. The pattern I've seen is to construct the range in the #[] call, which is slower. So it seems like that pattern is still doing unnecessary work, which makes me think that the cop that was added is still reasonable.

In any case, I agree that as it stands this is not really a comparison of #drop with #[], so I'll close this out. Happy to discuss other ideas on how to think about this one, but I think we should do them in a new PR that gets the comparison right from the get-go.


FYI: Array#drop overrides Enumerable#drop (see array.c) , so you compare Array#[] with Array#drop…

Ah yes, very true, thanks @mblumtritt! I'll rename this PR before closing to reflect that.

@parkerfinch parkerfinch changed the title Compare Enumerable#drop with Array#[] Compare Array#drop with Array#[] Nov 23, 2020
@parkerfinch parkerfinch deleted the drop-vs-infinite-slice branch November 23, 2020 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants