Consider using a lookup table to optimize the time of f1. Consider inserting subsets you discover into merge sorted list instead of quicksorting at the end. If the domain is small and finite you can implement some very fast merge sorts by populating sparse arrays.