Actually, my understanding is that GetRuntimeClassName should always return some public (i.e. metadata available) type. If there's no class type that satisfies that constraint, it should then return the "default" interface. As I recall, VC++ implemented it wrong at some point and always returned the (sometimes private) class name, but that was a bug.
Using GetIIDs is, indeed, bottlenecked on perf because there's no efficient lookup of types by IIDs; you have to scan the metadata yourself. What's worse, though, is that you don't even know what you need to scan - there's no guarantee that the metadata file for the given IID has already been loaded, and what do you do then?
(coincidentally, I believe that's why JS projection only looks at GetRuntimeClassName and ignores GetIIDs)