[pgsql-jp: 35219] Re: EUC-SJIS変換の改善について

Tatsuo Ishii t-ishii @ sra.co.jp
2005年 4月 9日 (土) 19:34:51 JST


石井です.

> 小川と申します。
> 
>  internalな話題ですが,日本語処理の話題なので日本語で議論できればと
> 思い,投稿させていただきます。
> (PostgreSQLのしくみ分科会へも投稿したので、重複して受信したかたは
> ご容赦ください)
> 
>  encodingがEUCのデータベースに対して,WindowsなどのSJISクライアントから
> 多量のデータを検索したとき,文字コードの変換処理がボトルネックになることが
> あります。
> そこで,EUC->SJIS変換の効率を改善するパッチを作成してみました。
> このパッチが新たなバグを作り出していないか?,もっと速くできないか?など
> ご意見お待ちしています。
[中略]
> (1)mic2sjisのループ内部で,pg_mic_mblenを実行しないようにした
>  オリジナルのコードでは,1文字ごとにpg_mic_mblenを実行して残りの文字の
> 長さを計算しています。さらに,pg_mic_mblenはpg_mule_mblenを実行します。
> このため,pg_mic_mblen/pg_mule_mblenの実行回数が多くなっています。
> 
>     while (len >= 0 && (c1 = *mic))
>     {
>         len -= pg_mic_mblen(mic++);
> 
>  これを以下のようにすることで,ループ内部でpg_mic_mblenを実行する必要が
> なくなります。
> 
>     unsigned char *mic_end = mic + len;
> 
>     while (mic <= mic_end && (c1 = *mic))
>     {
>         mic++;

たしかに!

> (2)mic2sjisでSJISに変換できない文字が現れたとき,micポインタの指す位置が
> 正しくならないときがあるのではないか?
> 
>         else if (c1 > 0x7f)
>         {
>             /* cannot convert to SJIS! */
>             *p++ = PGSJISALTCODE >> 8;
>             *p++ = PGSJISALTCODE & 0xff;
> 
>  ここでは現在の文字のバイト数を考慮していないため,micが次の文字を指して
> いることを保証できないと思います。
> そこで,micの位置を調節するために以下のコードを追加しました。
> 
>             /*
>              * Adjust a mic pointer. Because can't guarantee mic points
>              * next char here.
>              */
>             mic--;
>             mic += pg_mic_mblen(mic);

ここはちょっと疑問.というのはそもそもこのケースではpg_mic_mblen(mic)
は必ず1を返すので,これではmicが先に進まなくなるのではないでしょうか?

> 効果の測定(1): patch適用後のprofile結果
> Each sample counts as 0.01 seconds.
>   %   cumulative   self              self     total
>  time   seconds   seconds    calls  ms/call  ms/call  name
>  11.46      0.11     0.11   400008     0.00     0.00  euc_jp2mic
>  10.42      0.21     0.10  1301673     0.00     0.00  AllocSetAlloc
>   6.25      0.27     0.06  1300705     0.00     0.00  AllocSetFree
>   6.25      0.33     0.06   400000     0.00     0.00  FunctionCall3
>   6.25      0.39     0.06   100000     0.00     0.00  slot_deform_tuple
>   5.21      0.44     0.05   400008     0.00     0.00  euc_jp_to_sjis
>   4.17      0.48     0.04   900051     0.00     0.00  appendBinaryStringInfo
> 
>  長い実行時間を占めていたpg_mule_mblenやpg_mic_mblenがいなくなり,
> ボトルネックがeuc_jp2micへ移動したことが分かります。
> 
> 
> 効果の測定(2): 実行時間の測定
> profileオプションを外して(-O2のみにする),postgresをリビルドしてから
> 以下のコマンドで実行時間を測定。
> 
> $ time psql -f test.sql -o /dev/null
> 
> -- patch適用前
> real    0m2.964s
> user    0m0.850s
> sys     0m0.110s
> 
> -- patch適用後
> real    0m2.639s
> user    0m0.820s
> sys     0m0.060s
> 
> 実行時間(real)が約10%程,短縮できています。

10%の短縮とは素晴らしい.良かったらこれをcurrentにコミットさせてくださ
い.

# もしgenerate_series()を使ってDBアクセスをしないようにすれば,もっと
# はっきり効果が観測できるかも.

> 今回作成したpatch fileやprofile取得のメモなどは、以下のURLにおいて
> ありますので興味のある方はご参照ください。
> 
> http://www.hi-ho.ne.jp/a_ogawa/memo/pg/euc_jp_and_sjis/
--
Tatsuo Ishii



pgsql-jp メーリングリストの案内