-
Notifications
You must be signed in to change notification settings - Fork 375
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
Adding Array#reverse.index vs Array#size - Array#index - 1 #28
Conversation
Also note that these two implementations only produce the same result if there is only 1 of the item you're looking for in the array. For example:
I'll leave it up to you all whether you'd like to make a note of the difference, or not merge the PR because the examples aren't totally congruous. |
Hi Jake, as you mentioned, this is not very idiomatic and congruous. But I create a wiki page to document it. Thanks for the pull request, really appreciate it!!! ❤️ Have a nice day!!! |
@theunraveler I'm curious of the use case. I'm not seeing why you would do this I suppose. Mind explaining please? |
I just had a rather specific use case in a project I'm working on, actually. I'm writing some automation around naming hardware in a datacenter. The naming is based on the position of the device within its server rack from bottom to top, so I needed to get a list of all hardware in the rack, then sort it by position, then find the index of the hardware in reverse order, and use that index in the hardware name. In the case of a server rack, there are 120 sleds in a typical rack, so I noticed that Granted, the use case is not extremely common, and good caching can really make the discrepancy a non-issue, but I just thought it was interesting, so I posted it :-) |
Hi! Do you think this example is really useful? With
@JuanitoFatas I think this example is data specific and can be confusing. And also there is |
Using Array.size - ARRAY.rindex - 1 should actually retain the behavior of Array.reverse.index, since the first appearance on the reversed array corresponds to the last appearance in the original one. |
Note that which is faster depends on which end of the array is nearest. If you know there's only a single element or you just care about the index of any matching element, you can use index if you expect the element to be near the beginning of the array. #!/usr/bin/env ruby
require 'benchmark/ips'
ARRAY = [*1..1000]
def slow(e)
ARRAY.reverse.index(e)
end
def fast(e)
ARRAY.size - ARRAY.rindex(e) - 1
end
def faster(e)
ARRAY.size - ARRAY.index(e) - 1
end
Benchmark.ips do |x|
x.report('500 - reverse + index') { slow 500 }
x.report('500 - size - rindex - 1') { fast 500 }
x.report('500 - size - index - 1') { faster 500 }
x.compare!
end
Benchmark.ips do |x|
x.report('50 - reverse + index') { slow 50 }
x.report('50 - size - rindex - 1') { fast 50 }
x.report('50 - size - index - 1') { faster 50 }
x.compare!
end
Benchmark.ips do |x|
x.report('950 - reverse + index') { slow 950 }
x.report('950 - size - rindex - 1') { fast 950 }
x.report('950 - size - index - 1') { faster 950 }
x.compare!
end Calculating -------------------------------------
500 - reverse + index
31019 i/100ms
500 - size - rindex - 1
40222 i/100ms
500 - size - index - 1
42217 i/100ms
-------------------------------------------------
500 - reverse + index
339223.1 (±5.8%) i/s - 1706045 in 5.047903s
500 - size - rindex - 1
493997.5 (±3.2%) i/s - 2493764 in 5.053688s
500 - size - index - 1
503386.7 (±2.9%) i/s - 2533020 in 5.036366s
Comparison:
500 - size - index - 1: 503386.7 i/s
500 - size - rindex - 1: 493997.5 i/s - 1.02x slower
500 - reverse + index: 339223.1 i/s - 1.48x slower
Calculating -------------------------------------
50 - reverse + index 20669 i/100ms
50 - size - rindex - 1
25936 i/100ms
50 - size - index - 1
177229 i/100ms
-------------------------------------------------
50 - reverse + index 224896.8 (±1.5%) i/s - 1136795 in 5.056018s
50 - size - rindex - 1
273755.3 (±1.0%) i/s - 1374608 in 5.021783s
50 - size - index - 1
3361993.2 (±2.7%) i/s - 16836755 in 5.011957s
Comparison:
50 - size - index - 1: 3361993.2 i/s
50 - size - rindex - 1: 273755.3 i/s - 12.28x slower
50 - reverse + index: 224896.8 i/s - 14.95x slower
Calculating -------------------------------------
950 - reverse + index
67432 i/100ms
950 - size - rindex - 1
177032 i/100ms
950 - size - index - 1
26109 i/100ms
-------------------------------------------------
950 - reverse + index
914527.6 (±3.3%) i/s - 4585376 in 5.019921s
950 - size - rindex - 1
3344785.2 (±2.3%) i/s - 16818040 in 5.030894s
950 - size - index - 1
260991.6 (±3.2%) i/s - 1305450 in 5.007125s
Comparison:
950 - size - rindex - 1: 3344785.2 i/s
950 - reverse + index: 914527.6 i/s - 3.66x slower
950 - size - index - 1: 260991.6 i/s - 12.82x slower |
The code is a bit uglier and not quite as idiomatic, but I thought the performance improvement may make it work including. The performance gap grows pretty significantly with the size of the array; an array with 100,000,000 items shows the following, for example: