This technique was originally used to avoid script limits, and it's equally effective to avoid timeout limits.

Edit

As stated by Mike, you should make sure your filters are also correctly limiting records to avoid heap limits and query limits, and your field list should include only the fields necessary to complete the task.

Actually, the queries aren't the topic of this question-- they're asking about eliminating the inner loop. That aside, some notes: (1) you didn't check if t.whoId is null first, so NPE if there is no contact, and (2) you really should use t.WhoId.getSObjectType() == Contact.SobjectType instead of checking the key prefix, since, in theory, the key could change and this code would no longer operate as expected (I know it "shouldn't", but as an external developer, one cannot guarantee that).
–
sfdcfoxDec 12 '13 at 18:20

Both are good points. I plain forgot the first problem and never considered using getSObjectType in my comparisons before; I'll star using that in the future.
–
Mike ChaleDec 12 '13 at 19:02