眠い・・・
最近寝過ぎだと思います。8時間は絶対寝てるもんなー。
もうちょい工夫しよう。
メモリに入りきらないデータを扱う
タイトルのように、例えばWebデータを扱ってそこに出現する単語の頻度をカウントするような場合、どうするのが一番手軽で楽なんでしょうというお話。
勿論、多分ほとんどの人は知っていて、常識なのかもしれませんが、僕は最近気づきました。
まず、対象となる単語(研究によって異なるでしょう)だけを行単位で全部書き出します。
aaa bbb ccc
みたいに。
この時データ量があまりに多い場合複数ファイルに書き出した方が楽かもしれません。
その後は、単一ファイルの場合、
sort -S 500M | uniq -c | sort -nr -S 500M
で終わりです。
複数ファイルの場合は、全てのファイルをソートした後に、
sort -m -S 500M *.sort(ソート済みファイル) > merge.txt uniq -c merge.txt > count.txt sort -nr -S 500M count.txt > result.txt
だけでした。
sort の-Sオプションはこれだけのメモリに収めてくださいということです。
-mオプションでマージしながらソートしてくれます。
ちなみにマージソートの場合は、メモリをあまり使わなくてもファイルを上手く利用してソートが可能です。
そんなこんなで最近知ったトリビア。
クイックソートは実はマージソートよりも遅いです。
だから、C言語の標準ライブラリにあるqsortは内部でマージソートを利用しています。
(以前はクイックソート)
ちなみに計算量はどちらもO(nlogn)になります。
いろいろ考えて、自分でマージソートを実装するのが面倒だ…と思っていたときにUNIXコマンドにあることを思い出した俺は…orz
2007/07/20 追記:
Linuxなどで上記のコマンドを行った場合、LANGやLC_ALLの言語環境に影響を受けるようです。
(詳しくは調べていません。ただこの部分ではまりました。)
EUC-JPのテキストをja_JP.UTF-8の環境で行うと時間が通常の10倍以上かかり、おかしな結果になりました。
上手くいかない場合は、LANGUAGE=C(これはメッセージなので関係ないと思うけど)やLC_ALL=C、LANG=Cとして再度試してみてください。
おそらく、
もしくは
LC_COLLATE 並べかえ(ソート)の順番を設定する
この辺が原因。LC_ALLで上書きされます。
LC_CTYPE 文字定義、大文字、小文字など。これらは toupper、tolower、islower、isdigit のような関数で用いられる。
CppUnitを使え!
あとで追記予定。
autoconfとautomakeを使え!
えっと、autoconfとautomakeは研究用のプログラム書く時でも、ちょっとした処理を書く時でも、かなり便利です。
便利でした。
もっと前から知っていれば…。というか、怖がって手を出せないでいただけですが…。
3年前までは情報もあまりなかったけれども最近Web上にも日本語情報があふれているので最近チャレンジ。
手順はこのあたりかな?
http://www.saiin.net/~silphire/tips/autoconf.html
autoscan (/usr/autotool/devel/bin/autoscan) mv configure.scan configure.in configure.in、Makefile.amを書く。 autoheader aclocal touch NEWS README AUTHORS ChangeLog automake -a autoconf ./configure; make; make install
これだけで、ソースの追加も自由自在です。手書きでMakefileを書かなくていいってなんて素敵なんだ!
strchrとC++ stringのfindの速度差
find
void find(std::string &a) { for(int k = 0; k < 1000; k++){ a.find('b'); } } int main(void){ std::string a; a.reserve(10000000); for(int j = 0; j < 1000; j++){ for(int i = 0; i < 10000; i++){ a[i + j * 10000] = 'a'; } a[j * 10000] = 'b'; } for(int l = 0; l < 1000; l++){ find(a); } }
strchr
void find(const char* a) { for(int k = 0; k < 1000; k++){ strchr(a, 'b'); } } int main(void){ char *str; str = (char *) malloc(sizeof(char)*10000000); str[1] = 'b'; for(int j = 0; j < 1000; j++){ for(int i = 0; i < 10000; i++){ str[i + j * 10000] = 'a'; } str[j * 10000] = 'b'; } for(int l = 0; l < 1000; l++){ find(str); } free(str); }
で速度比較を行った。
strchr real 0m0.133s user 0m0.111s sys 0m0.021s find real 0m0.192s user 0m0.173s sys 0m0.019s
だいたい1.5倍かな?
ただ、文字列の構築に時間がかかっている可能性もあるので、一概に比較できないのが残念なところ。
プロファイラを取ったんだが、macだとC++のシンボル名がデマングルされないみたいです。
これ、なんとかできないかなぁ?
ちなみにコンパイラはどちらもg++で、最適化オプションはなしです。
Cで動的配列
まぁ、glib.hのGArrayがあるんですが、とりあえず実装してみた。
ポインタの扱いでハマる…。それから、
*p++ = *q++
の挙動とか。まぁ、いろいろ。
エキスパートCプログラミング
まだちゃんと読めてないけど、これは当たりだ!
今から読むのが楽しみです。K&Rも合わせてご紹介。
- 作者: B.W.カーニハン,D.M.リッチー,石田晴久
- 出版社/メーカー: 共立出版
- 発売日: 1989/06/15
- メディア: 単行本
- 購入: 28人 クリック: 721回
- この商品を含むブログ (199件) を見る
エキスパートCプログラミング―知られざるCの深層 (Ascii books)
- 作者: ピーターヴァン・デ・リンデン,Peter van der Linden,梅原系
- 出版社/メーカー: アスキー
- 発売日: 1996/03
- メディア: 単行本
- 購入: 17人 クリック: 404回
- この商品を含むブログ (78件) を見る
同時に買ったのは、「デバッガの理論と実装」「Linkers & Loaders」の2冊。
この辺り、もっと強くなっておきたい。