Posted at

LC_ALL=C.UTF-8 は安全か

More than 1 year has passed since last update.

普段は 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 って書きたいなー。)