Use class objects rather than strings for the dispatch cache

The only reason we're using strings is to pre-populate the cache, but
`Class#name` returns a new string instance on every call. This is a
pretty major source of memory usage. We don't technically need to
pre-populate the cache, and not doing so allows us to go back to using
cache objects