How are transactions in forks verified efficiently?
Transactions in forks are not verified completely until the node attempts to switch to that fork. Before that, only those checks are performed that don't depend on previous transactions. In the source code, there is a function CheckBlock, which does only some of the checks, and ConnectBlock, which checks everything. The latter function is called only when the block is about to be accepted into the longest chain, so the hash table of unspent outputs is available.