Основное различие между ними заключается в том, что UTF8 обратно совместим с ASCII. Пока вы используете только первые 128 символов, приложение, которое не поддерживает Unicode, может обрабатывать данные (что может быть преимуществом или недостатком, в зависимости от вашего сценария). В частности, при переключении на UTF16 каждую функцию API необходимо настроить для 16-битных строк, в то время как с UTF8 вы часто можете оставить старые функции API без изменений, если они не выполняют какой-либо обработки строк.
Также UTF8 не зависит от порядка байтов, в то время как UTF16 делает, что может усложнить ввод / вывод строки.
Распространенным заблуждением является то, что UTF16 легче обрабатывать, поскольку каждый символ всегда занимает ровно два байта. Это, к сожалению, не соответствует действительности. UTF16 - это кодирование переменной длины, где символ может занимать 2 или 4 байта. Таким образом, любые трудности, связанные с UTF8 в отношении проблем переменной длины, применимы и к UTF16.
Наконец, размеры хранилища. Еще один распространенный миф об UTF16 заключается в том, что он более эффективен в хранении, чем UTF8 для большинства иностранных языков. UTF8 занимает меньше памяти для всех европейских языков, которая может быть закодирована одним или двумя байтами на символ. Не-BMP символы занимают 4 байта как в UTF8, так и в UTF16. Единственный случай, когда UTF16 занимает меньше места, - это если ваш текст в основном состоит из символов в диапазоне от U + 0800 до U + FFFF, где хранятся символы для китайского, японского и хинди.
Джеймс МакНеллис выступил с превосходной речью на BoostCon 2014, подробно обсудив различные компромиссы между различными кодировками. Несмотря на то, что доклад называется Unicode в C ++ , вся первая половина фактически не зависит от языка. Видеозапись полного выступления доступна на канале Boostcon Youtube , а слайды можно найти на github .