From: "NARUSE, Yui" Date: 2008-01-20T06:54:37+09:00 Subject: [ruby-dev:33201] Re: Binary String 成瀬です。 Tanaka Akira wrote: > In article <4791F22E.8040207@airemix.com>, > "NARUSE, Yui" writes: > >>> ある時点まで ASCII で書いていたソースで、あるとき UTF-8 の文 >>> 字列リテラルを書いたとき、そのファイル中の他のすべての文字列 >>> リテラルも UTF-8 になる、というのはちょっとナニだな、と思い >>> ます。 > > そういえば、人間の都合ではなく実装の都合ですが、性能の話もあ > ります。 > > ASCII-8BIT や US-ASCII はシングルバイトエンコーディングなの > で、文字単位のインデックスを簡単にできることがエンコーディン > グを見ただけでわかります。 > > それに対し、UTF-8 などのマルチバイトエンコーディングだとそれ > なりに厄介な話になります。文字列に ASCII 文字しか入っていな > くても、そのことを確認できているかという問題があって単純には > いきません。 > >> この対策として、 >> b') ASCII only の文字列は常に US-ASCII を返す >> という手もあるのかな > > これは文字列に ASCII 文字しか入っていないことを調べる必要が > あるので、ちょうど上で述べた確認の話につながります。 > > まぁ、文字列の長さに比例した時間をかけていいのであればいいん > ですが。 えぇ、それは理解してます。しかし、その確認にかかるコストは以下の通りです し、問題の coderange_scan は文字列リテラルの場合は作った時点で終わってい ますから、問題ないかと思います。つまり、a) b) b') とも、実装・動作コスト はほとんど変わらないと思います。 static VALUE rb_str_is_ascii_only_p(VALUE str) { int cr = rb_enc_str_coderange(str); return cr == ENC_CODERANGE_7BIT ? Qtrue : Qfalse; } int rb_enc_str_coderange(VALUE str) { int cr = ENC_CODERANGE(str); if (cr == ENC_CODERANGE_UNKNOWN) { rb_encoding *enc = STR_ENC_GET(str); cr = coderange_scan(RSTRING_PTR(str), RSTRING_LEN(str), enc); ENC_CODERANGE_SET(str, cr); } return cr; } #define ENC_CODERANGE(obj) (RBASIC(obj)->flags & ENC_CODERANGE_MASK) if 文一つの違いですね。 static int single_byte_optimizable(VALUE str) { rb_encoding *enc = STR_ENC_GET(str); if (rb_enc_mbminlen(enc) == 1 && rb_enc_mbmaxlen(enc) == 1) return 1; /* Conservative. It may be ENC_CODERANGE_UNKNOWN. */ if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT) return 1; /* Conservative. Possibly single byte. * "\xa1" in Shift_JIS for example. */ return 0; } -- NARUSE, Yui DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA