Batch-loading of Users/UserIdentity is a common-enough task - there's a helper for that, UserArray and a subclass, UserArrayFromResult. These are designed around global state and need complete rewrite.
UserIdentityLookup::getUserIdentityBatchFromUserIDs( array $ids, bool $fetchUserAccounts = false // Leave out for now ): Something; UserIdentityLookup::getUserIdentityBatchFromNames( array $names, bool $fetchUserAccounts = false // Leave out for now ): Something
The 'fetchUserAccounts' feature could be left out for now, it's an optimization idea for when we introduce UserAccount interface. getUserIdentityBatchFromUserIDs is guaranteed to return users that actually have an account, as a lot of users of UserArray::newFromIDs will not be satisfied with just UserIdentity. Batch query for actor table vs user table by IDs are probably similarly complex, so maybe we actually would want to just return an array of UserAccount instances.
For getUserIdentitiesFromNames the situation is even more complex - we might want to get only registered users, or might want to get UserIdentities for anons and UserIdentities for registered, or UserAccount for registered and UserIdentity for anon. Thus, maybe we'd need the bool flag parameter in the future.
I'm not quite sure what to return though - Iterator or an array, or a ArrayAccess implementation. Currently, UserArray is an iterator which fetches the rows in a batch, but instantiates the User objects lazily. I'm not sure laziness will really be needed for UserIdentity/UserAccount - the objects are much cheaper to instantiate, plus in practice the result array is always fully traversed. So I propose we just return UserIdentity[].