When this was posted to lobsters someone shared this relevant link: https://curiouscoding.nl/posts/static-search-tree/
I'm somewhat curious about the initial problem:
> Consider the following real problem, one of the steps in scikit-learn’s gradient histogram boosting algorithm:
> You have a large array of floating point numbers.
> You want to assign them to the integer range 0-254, spread out evenly.
Naively I would consider sorting the initial array and then using something like `batched` from itertools to chunk them into the 255 buckets - binary search will give you a bunch of random accesses, and sorting can be cache-oblivious (eg efficient for arbitrary data sizes)
But I'm somewhat concerned I don't fully understand the underlying problem being solved with this step, so I might be misunderstanding the intended result
This bit is interestingly unintuitive - to go faster, do more iterations:
> As far as the number of while loop iterations, I’m instead going to iterate a fixed number of times, log2 of the number of buckets. For some value this might involve a bit more work, if previously the bucket would be found in an iteration or two, but the saving in speed from avoiding branch mispredictions will make it worth it.
<code> let middle = min_idx + ((max_idx - min_idx) / 2); </code>
Respect!
“ How do you speed up computational Python code? A common, and useful, starting point is”
A better starting point is: use a better language. Python is terrible and unbearably slow. If you need anything serious or performant, switch to something else.
I think putting the buckets in eytzinger layout might help with cache locality here? though on the other hand they might all fit into cache anyways..
I'd also want to try interpolation search for this (not necessarily linear interpolation since we're doing floats) - you can take much better guesses than "it's in the middle somewhere" by not having to look at the data through a 1-bit-wide pinhole as comparison algorithms do.