Use case: The list is used as a buffer, that is re-used and in
each iteration the list is cleared.
Now that clear() does not replace the data array there is no
garbage collection and we do not have to allocated one or
several new arrays in the next iteration.
You can still free the associated memory by calling clear() + trim().
- Remove TODO in unionUnsorted, because I don't think there is a much
better solution.
- Remove TODO for lastIndexOf, because it has been implemented.
- Use local variables for size in unionSorted.
The algorithms for removeAll, retainAll and removeIf were almost
identical. The main difference was, that removeIf calls a lambda,
whereas removeAll and retainAll executed the check directly. Both
methods call indexOf on an IntList, which easily outweighs the extra
cost of the lambda.
It makes sense to consolidate and remove the duplicated code.
I ran a few benchmarks with different list sizes before the replacement.
The results are not as clear as I would have liked. In some cases,
especially for short lists, the special implementations of
removeAll/retainAll were up to 10% faster. In other situations I saw
50% difference the one day, but could not reproduce those results a
day later. This leads me to believe, that my test setup is not
trustworthy.
That means I stay with what I now. The code is identical with one tiny
difference. And that difference shouldn't matter, because indexOf is
much more expensive.
A list can be sorted after shuffling. The trivial cases are
the empty list and a list with only one element or lists
with only identical elements. Lists with only a few elements
have a non-negligible chance to be sorted after shuffling.