不知道u16string是不是utf-16.
utf-16原本对应unicode基本平面(65536个字符,其中汉字为gbk+cjk-extA,约有2.8万个),后来unicode字符集不断扩充,超出了基本平面的容纳范围。超出基本平面的汉字utf-16编码就不是双字节编码了,这时utf-16就名不符实了,它成了和utf-8一样的变长编码。当然我们一般人用的字符都在基本平面内,几乎不太可能用到超出两个字节的utf-16字符。所以实践中,还是有不少人直接把utf-16的字符串当成定长变码来对待。但理论上,utf-16已经不符合它原来的定义了(于是出现了utf-32,用来代替utf-16,这个是真正的定长编码方式,不过与utf-8比起来,空间效率更低)。
基本平面内的汉字,三字节的utf-8编码和两字节的utf-16编码,对于今天的计算机存诸技术和网络带宽而言,不是一个值得纠结的点,如果加上zip等无损压缩手段,两字节相对于三字节编码的空间优势更是可以忽略不计(比如在epub、odt文件中)。对于变长的utf-8编码,直接取下标定位字符技术上也是可以做到的。
定长编码的唯一优势是,取下标操作的时间复杂度是常数,而变长编码取下标操作的时间复杂度是线性的。以今天的计算机速度,定长编码(基本平面内的utf-16, 所有平面内的utf-32)的这点优势不值一提。
在编程语言中向程序员暴露每个字符的编码长度(u16、u32)就是误入歧途,程序员只须关心他存的是哪些字符和编码方案即可(比如 a = string('国家',coding='utf-32')),程序设计语言应该封装具体的码长信息,所有关于字符串的操作都应该基于字符而非关注于其底层编码,非字符/二进制数据应该存放在bytes中,这时应该向程序员暴露字节长度。
utf-8的优势是很明显的。首先它是自同步的,无需额外加入大端小端信息,允许读取程序从任何位置开始并立即检测到字符边界,这是非常重要的一个优点。其次它采用变长编码方式,对最常用的英文字母采取1个字节编码,节省了大量空间。由于长度可以不断扩充,因此本身保持开放性,可以和unicode一同演进。采用变长编码方式还使程序不得依赖/限定文字的编码长度,在更抽象的水平上操作文字,而不是依赖于strcpy、strcat、strstr、strlen、strdup等底层函数。变长编码方式也不影响grep等RE工具的使用。
定长编码不值得留恋。
【 在 hgoldfish 的大作中提到: 】
: 如果多用中文的话,应该是 u16string 最省空间。基本上一个汉字对应两个字节。
: 而且 utf-8 的话,一个汉字基本上对应三个字节。
: python 和 Qt 都会做我刚才说的优化,自动根据 unicode 编码范围,选择适合的存储类型来使用。一来可以节省空间,二来提升处理效率。比如 u8string 里面,想要迭代处理一个个 unicode 字符,一会是一个字节,一会儿是三个字节。效率很差。
: unicode_string[i]
: 就这个简单的取下标,都是大麻烦。
--
修改:seablue FROM 111.200.40.*
FROM 111.200.40.*