5

Given an element and an array, the Ruby#index method returns the position of the element in the array. I implemented my own index method using binary search expecting mine would outperform the built-in one. To my surprise, the built-in one ran approximately three times as fast as mine in an experiment.

Any Rubyist knows the reason why?

sawa
  • 165,429
  • 45
  • 277
  • 381
Terry Li
  • 16,870
  • 30
  • 89
  • 134
  • 2
    Who said the Ruby `#index` method was not already implemented with binary search? And furthermore, who said that method was implemented in Ruby at all? :-) – Platinum Azure Sep 15 '11 at 19:13
  • @Platinum Azure Oh I see, it might be implemented in C with binary search. Thanks a lot! – Terry Li Sep 15 '11 at 19:20

1 Answers1

11

The built-in #index is not a binary search, it's just a simple iterative search. However, it is implemented in C rather than Ruby, so naturally it can be several orders of magnitude faster.

wersimmon
  • 2,809
  • 3
  • 22
  • 35
  • Thanks. That's really weird, though. Was there a reason why they didn't adopt the binary search approach? – Terry Li Sep 15 '11 at 19:59
  • 1
    A binary search involves being able to compare two elements, as opposed to just being able to see if two elemnts are equal. Also notice the documentation says it returns the *first* object equal to the argument — a binary search would not always return that element. Besides, my version of #bsearch (assuming the array is sorted) doesn't seem slower than #index: https://gist.github.com/1220440 – Mon ouïe Sep 15 '11 at 20:48
  • I assume your #bsearch implementation is able to beat the difference between Ruby and C with that between binary search and sequential search? – Terry Li Sep 15 '11 at 21:18
  • 3
    A binary search also requires a sorted array, which is O(n log n) - so if #index "knew" it was to be called enough times, that would be worth doing, but not in the general case. – jkebinger Sep 15 '11 at 21:54
  • @jkebinger True. I forgot to mention that my array be a sorted one. Thanks for your input! – Terry Li Sep 15 '11 at 22:14
  • Thanks @LBg, I couldn't figure out how to get it to link directly to the line. I wonder why they don't just use `...#1171` ? – wersimmon Sep 16 '11 at 02:41