LC_ALL=C.UTF-8 は安全か

  • 19
    いいね
  • 0
    コメント

普段は mac で ja_JP.UTF-8 を使ってるけど、 Linux では予想しない挙動の変化が起きるのを嫌って C locale を使う人、いますよね。僕も常にではないけれど結構 C locale 好きです。

でも、 C locale を使うと、 vim が (set encoding=utf-8 を書いていないと) デフォルトで latin1 になって文字化けしまくったり、 Python が (export PYTHONIOENCODING=utf-8 しておかないと) 標準入出力がasciiになって UnicodeError になったりしてツラい気持ちになることもあります。

そんなときは、 LANG=C, LC_CTYPE=en_US.UTF-8 で LC_ALL は設定しないようにするのがただしい locale の設定方法なんですが、最近のモダンな Linux に搭載されてる C.UTF-8 はそのかわりに使えるのでしょうか?

気になるのが、 LC_COLLATE です。 Unicode に乗っ取った順序が有効になって、 http://unix.stackexchange.com/questions/169739/why-is-coreutils-sort-slower-than-python みたいな問題が起こらないでしょうか。確認しておきましょう。

# from http://unix.stackexchange.com/questions/169739/why-is-coreutils-sort-slower-than-python

$ cat letters.py
import string
import random

def main():
    for _ in range(1_000_000):
        c = random.choice(string.ascii_letters)
        print(c)

main()

$ python3.6 letters.py > letters.txt

$ LC_ALL=C time sort letters.txt > /dev/null
        0.35 real         0.32 user         0.02 sys

$ LC_ALL=C.UTF-8 time sort letters.txt > /dev/null
        0.36 real         0.33 user         0.02 sys

$ LC_ALL=ja_JP.UTF-8 time sort letters.txt > /dev/null
       11.03 real        10.95 user         0.04 sys

$ LC_ALL=en_US.UTF-8 time sort letters.txt > /dev/null
       11.05 real        10.97 user         0.04 sys

UTF-8 の部分は LC_CTYPE にだけ影響して、 LC_COLLATE には影響しないみたいですね。安心して C.UTF-8 を使えそうです。

(本当は LC_CTYPE=UTF-8 って書きたいなー。)