[pgsql-jp: 35223] Re: EUC-SJIS変換の改善について
a_ogawa
a_ogawa @ hi-ho.ne.jp
2005年 4月 10日 (日) 00:25:33 JST
小川です。
> > 片岡です。
> > > 石井です.
> > >> mic--;
> > >> mic += pg_mic_mblen(mic);
> > > ここはちょっと疑問.というのはそもそもこのケースではpg_mic_mblen(mic)
> > > は必ず1を返すので,これではmicが先に進まなくなるのではないでしょうか?
> ところで、ここに入ってくるケースって、どんな場合を想定してますか? あ
> る程度想定できているから、必ず1を返すと考えられるわけですよね。私はイレ
> ギュラーなパターンを想定していると思ったので(1とは限らないと思ったの
> で)上記のやり方には賛成なんです。
私もこのコードが必要なケースがあるのか疑問なのですが、この関数を
見ただけでは必ず1になることが保証できないと思い、手当てしたほうが
安全だと考えました。
> 石井です.
> 10%の短縮とは素晴らしい.良かったらこれをcurrentにコミットさせてくださ
> い.
ありがとうございます。
ぜひコミットしてください。
実はあといくつかアイデアがあって、効果の測定やパッチの作成は別途行いたいと
思いますが、簡単に紹介させていただきます。
アイデア1: strlenを省略する
現在のeuc_jp_to_sjisでは以下のように、pallocでバッファを確保してから
euc_jp2mic, mic2sjisでeucからmic(mule internal code)、micからsjisへ
変換しています。
buf = palloc(len * ENCODING_GROWTH_RATE);
euc_jp2mic(src, buf, len);
mic2sjis(buf, dest, strlen(buf));
pfree(buf);
ここでmic2sjisの実行時にstrlenでmicの文字列の長さを計算していますが、
直前のeuc_jp2micを以下のようにすることで、strlenを省略できます。
static int
euc_jp2mic(unsigned char *euc, unsigned char *p, int len)
{
int c1;
unsigned char *p_start = p; /* save start of buffer */
while (len >= 0 && (c1 = *euc++))
{ ... 省略 ...
}
*p = '\0';
return p - p_start; /* return length of mic string. */
}
こうするとeuc_jp2micがmicの文字列の長さを返すので、euc_jp_to_sjisは
以下のように書けます。
int mic_len;
buf = palloc(len * ENCODING_GROWTH_RATE);
mic_len = euc_jp2mic(src, buf, len);
mic2sjis(buf, dest, mic_len);
pfree(buf);
アイデア2: palloc/pfreeを省略する
前述のeuc_jp_to_sjisを以下のようにすることで、文字列が短いときに
ローカル変数を使うことでpalloc/pfreeを省略できます。
(これはコードの可読性は悪くなるので、あまり良くないかもしれません)
#define LOCAL_CONVERT_BUF_SIZE 1024
if(len * ENCODING_GROWTH_RATE < LOCAL_CONVERT_BUF_SIZE) {
unsigned char buf[LOCAL_CONVERT_BUF_SIZE];
euc_jp2mic(src, buf, len);
mic2sjis(buf, dest, strlen(buf));
} else {
unsigned char *buf = palloc(len * ENCODING_GROWTH_RATE);
euc_jp2mic(src, buf, len);
mic2sjis(buf, dest, strlen(buf));
pfree(buf);
}
これらのアイデアはeuc->mic->sjisという変換の枠組みを維持しながら、
少ないコード修正で性能を向上させようする試みです。
恐らく最速の解は、eucからsjisへ直接変換できるようにすることだと
考えてますが、コードの変更範囲が多くなりそうで、少し躊躇してます。
---
小川 淳 (a_ogawa @ hi-ho.ne.jp)
pgsql-jp メーリングリストの案内