For some situations, e.g. if you can waste some memory and if you now that most characters you encounter will be from the Basic Multilingual Plane, you could try even more aggressive lookup tables, for example first calculate the length in bytes by the method described above and if it is 1 or 2 bytes (maybe 3 makes sense too), look up the decoded char in a table.