mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Replace hand-rolled binary search with bisect_left (#50410)
The `bisect` module exposes a `bisect_left` function which does basically what the bulk of `_lower_bound` does. From my tests, it is slightly faster (~5%) in the probably common ideal case where `arr` is short. In the worst case scenario, `bisect.bisect_left` is *much* faster. ``` >>> arr = list(range(60)) >>> cmp = 59 >>> %timeit _lower_bound(arr, cmp) 736 ns ± 6.24 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) >>> %timeit bisect_lower_bound(arr, cmp) 290 ns ± 7.77 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) ``` I doubt this is a huge bottleneck or anything, but I think it's a bit more readable, and it's more efficient, so it seems like it's mostly a win. This commit *will* add a new unconditional import for `bisect` when importing `util.dt`, and `bisect` is not currently imported for any of the standard library modules. It is possible to make this conditional by placing `import bisect` in the _lower_bound function, or in the function it's nested in.
This commit is contained in:
parent
f5541a468e
commit
efa5c59559
@ -1,6 +1,7 @@
|
||||
"""Helper methods to handle the time in Home Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
import bisect
|
||||
from contextlib import suppress
|
||||
import datetime as dt
|
||||
import re
|
||||
@ -265,15 +266,7 @@ def find_next_time_expression_time(
|
||||
|
||||
Return None if no such value exists.
|
||||
"""
|
||||
left = 0
|
||||
right = len(arr)
|
||||
while left < right:
|
||||
mid = (left + right) // 2
|
||||
if arr[mid] < cmp:
|
||||
left = mid + 1
|
||||
else:
|
||||
right = mid
|
||||
|
||||
left = bisect.bisect_left(arr, cmp)
|
||||
if left == len(arr):
|
||||
return None
|
||||
return arr[left]
|
||||
|
Loading…
x
Reference in New Issue
Block a user