natsuの秘密基地です
カレンダー
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
カテゴリー
プロフィール
HN:
natsu
性別:
男性
趣味:
酒など
自己紹介:
ここに書かれていることはフィクションです。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
UTF8。
それにマクロと同じくらいにしか速くならない気がする。
何回かやったけど、
大体2倍から2.5倍は確実に速い。
マルチバイト文字ってねぇ。
難しいんですよ。
よくわかんないよ。わたしゃ。
鬼車にUTF8で渡していろいろ試したんだけども、
戻り値が案の定、何バイト目か。で、かえる。
そこまでの文字数を手に入れるにはどうすればいいんだろう。
UTF8は一個の文字を表現するためのバイト数が可変だ。
mblenでその文字何バイト?
を繰り返しやればいいのだろうか。
ええのんか。ええのんか。みたいな。(意味不明)
もう少し速そうな方法があればいいんだけども。
mblenが関数じゃなくてマクロだったらいいなあ。
とはおもった。
たぶん、こういうときにこそ、
関数呼び出しのオーバーヘッドを気にしなければいけない気がするから。
マクロだったらそのへんで繰り返し処理の効率がまだましになる。
それこそ、[lengthGetter length:str]
とかやっちゃうと大変なことになる気がする。
アセンブラで速くなんないかな、とか検討するにしてもね。
今それやっちゃうと、
iPhoneやiPadとか。柔軟性が無くなっちゃう。
それにマクロと同じくらいにしか速くならない気がする。
たぶんだけど、どの環境でもマクロが最も妥当。
勘だけど。
なんかGTKにそういう用途のコードがあるらしい。
ここでそのコードの引用を見つけた。
コードから察するに、
UTFの文字の先頭1byteと、
256の長さの配列で判定をするというものだと思う。
たぶんこういうことだと思う。
case1
その文字の1bit目が0の場合、
その1byteで一つの文字
case2
その文字の3bit目までが110の場合、
そのbyteと次のbyteの2byteで一つの文字
case3
その文字の4bit目までが1110の場合、
そのbyteと次の2つの3byteで一つの文字
case4
その文字の5bit目までが11110の場合、
そのbyteと次の3つの4byteで一つの文字
case5
その文字の6bit目までが111110の場合、
そのbyteと次の4つの5byteで一つの文字
case6
その文字の7bit目までが1111110の場合、
そのbyteと次の5つのbyteの6つで一つの文字
めんどい。要するに
0x000 <= 1byte目 <= 0x7F 1byte
0x80 <= 1byte目 <= 0xBF 得体の知れない何か
0xC0 <= 1byte目 <= 0xDF 2byte
0xE0 <= 1byte目 <= 0xEF 3byte
0xF0 <= 1byte目 <= 0xF7 4byte
0xF8 <= 1byte目 <= 0xFB 5byte
0xFC <= 1byte目 <= 0xFD 6byte
0xFEか0xFF == 1byte目 それらではない何か
ってことなので、
unsigned char charLength[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
//ここまでで7F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
//ここまででBF
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
//ここまででDF
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
//ここまででEF
4,4,4,4,4,4,4,4,
//ここまででF7
5,5,5,5,
//ここまででFB
6,6,
//ここまででFD
1,1
//FEとFF
};
って配列を使って、
文字のバイト数 = charLength[1byte目];
って感じで文字のバイト数が得られる。
で、ここまでくると、
gtkのコードにあるようにマクロが組めるようになる
えっとbyte型って、あったっけ、なかったっけ。
#define UTF8STEP(p) ((p) + charLength[*(unsigned char *)(p)])
pがchar *でそのまさに指し示している文字の先頭1バイトを
配列に渡して文字数を返してもらい、
それをpに足せば次の文字の先頭のアドレスになる。
これを検索ヒットの位置まで繰り返していけば、
そこまでの文字数が手に入ると。
適当に文字列を思いついて、
最後の方にヒットするように正規表現を書いて、
なんとなく何バイト目かを出して、
その何バイト目か、から何文字目かを出すのに計測。
って感じで計測をすればいいと思ったので、
このエントリーの下書きのファイルを読み込んで、
最後の方にヒットするように条件を書く。
改行があると頭おかしくなりそうなので、
あらかじめ取り除いておく。
mblen_l
2010-05-17 16:28:26.956 onitest[23352:903] Elapsed time: 0.000142
マクロ
2010-05-17 19:32:32.280 onitest[24805:903] Elapsed time: 0.000048
あー。やっぱマクロでやった方が速いっすねー。
ほら計測結果みてごらんなさい。
もう全然違う。
何回かやったけど、
大体2倍から2.5倍は確実に速い。
っていっても、
一回だけやるんだったら、どちらも問題にならないくらい速い。
どちらでもいいと思った。
PR
この記事にコメントする