本当は[言語]タグではないような。
MozillaハッカーであるRobert O'Callahanによる、 「UTF-16はダメ、UTF-8でいいじゃん」という話。
私も前に書いたような気がするけど、 UTF-16は良くない。まず、第一にUTF-16はバイト単位のCES(Character Encoding Scheme)でないので エンディアンの影響を受ける。これは結局同じ名前で2種類のCESがあるのと同じである。
それを区別するための方策がBOM(Byte Order Mark)だが、 これが輪をかけてよくない。 BOMの文字としての意味は「ZERO WIDTH NON-BREAKING SPACE」なので、 これは見えない文字である。付いているかどうかひと目でわからない文字は 面倒なだけである。うっかり文字列やファイルの途中に混じってしまったら目も当てられない。
さらにその全身前身であるUCS2と比較して、
UTF-16は固定長ではない。ので、n番目の文字をアクセスするコストは
普通に実装すればO(n)である。
UCS2の頃に重大な選択を「してしまった」Javaとかはともかく、 これから選ぶならUTF-16はありえない。 もう、ダメの三連荘。
UTF-16がダメなら、なにを選ぶのか。 ここではUTF-8を推奨している。私も(条件つきで)賛成する。
UTF-8は、エンディンアン問題と無縁である。 BOMも不要だ(付けられるけど)。メモリ効率もUTF-16よりはずっといいし。 可変長であるという点はUTF-16同様だけど、 それもそんなに問題ではない。
というのも、そもそもn番目の要素へのアクセス(ここではCharAt(n)と呼ぶ)は そんなに登場しないからだ。実際に頻繁に現れるのは 文字の検索であり、それはもともとO(n・m)だったりするし、 UTF-8でBoyer Mooreを実装するのもたやすい(今のRubyはKarp Rabinを使ってるけど)。
LarcenyというScheme処理系でどのように文字列を表現するか、という話。 前にShiroさんが話してたものだね。
紹介されているのは以下の7通り。
興味深いのはやはりrecord2やrecord1。 ただ、これってSchemeに閉じている時にはいいんだけど、 Cから文字列がほしい時にはrecord1やrecord2のフォーマットのままでは困るので、 毎回UTF-8なりUTF-16なりに変換してやる必要が出てきそうだ。 そうなったときに、変換やメモリ割り当てのコストがどのくらい効いてくるかが 興味深いところだ。少なくともRubyでは難しそうだなあ。
This work is licensed under a Creative Commons License.
あけおめ。「さらにその全身」→「さらにその前身」のまちがいかな?
UTF-16が一番ダメなところは、ほとんどケースでUCS2とみなしても正しく動いてしまう為にサロゲートペアを考慮しないおばかさんが大量生産される事だと思う。<br>何度説明してもだって僕のところではうごくんだもん。とか抜かしやがる。
record1はおもしろそうだなぁと思ったのですが、これ結局日本語の場合UTF-8より容量食うんですね。Rubyの場合str_nthでsingle byteの場合はポインタに+nthするだけなので変わりませんから、non-asciiの場合のみですね。「CharAt(n)の登場頻度は低い」という仮定ではこれもうれしさは少ないでしょうし・・・。<br>もっとも、この手のバイト列と実際の格納形式が異なる場合の処理を入れておくと、ISO 2022シリーズを文字集合番号+バイト列でステートフル化したうえで格納、という方法を使いやすくなるので、そういったメリットはあるかもしれません。
意図的かと思いますが、物理では"String Theory"は「弦理論」(重力を含む素粒子物理の理論)の事を指すのでタイトルを見てびっくりしました。http://en.wikipedia.org/wiki/String_theory