Cache all ndarray typecodes

A table caches the typecodes of ndarrays inside the dispatcher, as
long as they are of a certain type and number of dimensions. For
example, ndarrays with a Record dtype are not cached, and each
time the typecode for one of these arrays is required, a slow call
back into Python is required.

This commit adds caching of the typecodes of all other ndarrays in
order to eliminate calls into Python code for any type whose
typecode has been found previously. This includes both Record-type
arrays and arrays of higher dimensions.
This means that if the number of dimensions is out of bound, dtype_num_to_typecode() will always be called despite being ignored? OTOH, perhaps the compiler optimizes that away.