Optimize Range#bsearch for beginless/endless ranges

On Range#bsearch for endless ranges, we try positions at `begin + 2**i` (i = 0, 1, 2, ...)
to find a point that satisfies a given condition.
Subsequently, we perform binary searching with the interval `[begin, begin + 2**n]`.

However, the interval `[begin + 2**(n-1), begin + 2**n]` is sufficient for binary search
because `begin + 2**(n-1)` does not satisfy the condition.

The same applies to beginless ranges.
This commit is contained in:
Kouhei Yanagita 2023-09-16 12:10:09 +09:00 коммит произвёл GitHub
Родитель 67dedf8cf6
Коммит 7d08dbd015
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 11 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,9 @@
prelude: |
r = (1..)
benchmark:
'10**1': r.bsearch { |x| x >= 10 }
'10**2': r.bsearch { |x| x >= 100 }
'10**3': r.bsearch { |x| x >= 1000 }
'10**4': r.bsearch { |x| x >= 10000 }
'10**5': r.bsearch { |x| x >= 100000 }

Просмотреть файл

@ -758,6 +758,7 @@ range_bsearch(VALUE range)
return bsearch_integer_range(beg, mid, 0);
}
diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
beg = mid;
}
}
else if (NIL_P(beg) && is_integer_p(end)) {
@ -770,6 +771,7 @@ range_bsearch(VALUE range)
return bsearch_integer_range(mid, end, 0);
}
diff = rb_funcall(diff, '*', 1, LONG2FIX(2));
end = mid;
}
}
else {