-
-
Notifications
You must be signed in to change notification settings - Fork 32.9k
gh-138946: list.sort
enhancement proposal: Adaptivity for binarysort
#138947
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
base: main
Are you sure you want to change the base?
Conversation
Since you asked for more ideas... Tim and I once talked about things like this here: #116939 |
This is pretty much what I have done to incorporate it so not to damage performance of non-target cases. In many ways it resembles galloping approach. It switches on/off and grows "time-off" parameter on failed attempts. |
I have a simpler Python implementation of the adaptative algorithm. I made it look like the C implementation, kind of. def adaptative_binary_insertion_sort(a, n=0, ok=0):
n = n or len(a)
last = 0
for ok in range(ok + 1, n):
pivot = a[ok]
L = 0
R = ok - 1 # Ensures that pivot will not compare with itself.
# M is the index of the element that will be compared
# with the pivot. So start from the last moved element.
M = last
while L <= R:
if pivot < a[M]:
R = M - 1
last = M # Stores the index of the last moved element.
else:
L = M + 1
last = L # Stores the index of the last moved element.
M = (L + R) >> 1
if last < ok: # Don't move the element to its existing location
for M in range(ok, last, -1):
a[M] = a[M - 1]
a[last] = pivot # Move pivot to its last position. It's so simple, I think it can be implemented by modifying a few lines of the original |
V1 Info (outdated)
Currently, adaptivity is simple.
last
)diff = abs(new_idx - last)
last
last += diff
binarysort
It is primarily targeted at data already sorted to significant degree (e.g. stock price data).
However it so happens that it handles some other patterns as well.
e.g.:
[-1, 1, -2, 2, -3, 3, ...]
.diff
will always be the full length of sorted part, so it will be jumping from one end to the next in 1 step.Microbenchmarks
For optimised comparisons this has little effect.
As can be seen, the worst case is small random data.
But in the same way that small data feels the biggest adverse effect, the positive effect is also the largest as greater (or all) portion of data is sorted using
binarysort
only.However, the impact is non-trivial for costly comparisons.
list.__lt__
is probably the fastest of all the possible ones.For Pure Python user implemented
__lt__
, the impact would be greater.V3 Getting closer to desirable result.
Raw integers & floats (specialised comparison functions)
Above wrapped into lists
list.sort
enhancement proposal: Adaptivity forbinarysort
#138946