Performance improvements for IO.select.

* Avoid HashMap for small sets of items.
* Avoid HashSet for small sets of items.

HashMap and HashSet are very memory-inefficient for small numbers
of items. HashMap::Node was highest in early alloc profile.

* Avoid Java 5 iteration when numeric iteration will do.

Java 5 iteration creates at least an Iterator and often other
support structures to support it.

* Use builtin channels when possible (pipe fixed in this commit).

ENXIO selectors cannot be combined with builtin selectors,
requiring us to select them in a separate thread. We're using our
executor, but there's other overhead for native select like an
additional pipe per selector, native memory for signaling the pipe
on the other end, etc. The threading may be the biggest hit, since
it requires more communication.

* Eliminate more unnecessary collections from MRI logic.

We do not need to turn our lists of keys into primitive arrays.