Before optimizations:
7.065002638002625

After optimizations:
4.69557189499028

The main speedups come from using a set instead of a chain of boolean comparisons and passing the upper bound of the table into the binary search instead of calling length on the table for each run.