観察日記 2010-03-08

続String.buffer

ついにベンチマーク

なんで彼らはパッチも書かず、ベンチマークも取らないんだろうと話していたら、ついにベンチマークが。

そして、ついに完結!?

[ruby-core:28541] Re: [Feature #905] Add String.new(fixnum) to preallocate large buffer でかい malloc って実際に書き込むまでプロセスのメモリ使用量としては観測されないとかあったっけ
mallocときいて(ガラッ
専門家が来た
いや専門家ではない
よくわからんのだが
普段は s << t のときのバッファ伸長は、内部的には何がおこってるの?
バッファが足りなければ realloc ではなかろうか
reallocが減るならmalloc実装によらず速くなりそうなもんだけど
でも、topでみるとメモリ使用量増えてないとかいってるな
realloc するとき倍に伸ばす
ならし計算量で realloc のコストは O(1) となる
あれ、malloc内でなにか最適化があるんだっけかな。ごそごそ
ああ、ちゃんとmremapつかってるな
よって、crubyではJRubyのような問題はない

解説

Javaの世界だとすべてのメモリがいったんJavaVM経由するので、以下のようになる(はず) 1) 新しいバッファを用意する(rubyと同じように倍々に伸長) 2) 内部データをコピー 3) 古い領域を捨てる
これはSTringがGB単位で長いときにはコピーがやたら遅い
話を戻すと、mremapを使うことにより一番遅い(2)のコピーをしなくてすむようになるので、劇的に速いわけですな
crubyえらい
イマドキのmallocがエラいだけかもしれん
mremapって元のメモリアドレスはどうなるんでしょうか
MREMAP_MAYMOVE の説明をよんでちょ
このフラグが指定されると、カーネルは必要があればマッピングを新しい仮想アドレスに
再配置することができるマッピングが再配置されると、古いマッピング位置への絶対ポインタは無効になる (マッピングの開始アドレスからの相対オフセットは有効のままである)。
mremapはmmapに対するrealloc相当なので
内部的にはページテーブル作り直して、違うアドレスにページを貼り付け直しているだけなので、ゼロコピー
とか、そういうはなし
rubyのstring appendはゼロコピーだったんだよ!(ガラッ
mremap ってマルチコア環境下での性能ってどうです?
マルチコアでロック競合は増える。もちろん
ページディレクトリ単位でロックする,感じの同期コストかしら
でも、普通はmemcpyのほうが何倍もおそいし、memcpyするときのキャッシュ汚染が速度的な意味では致命的なので、そんなに問題にはならないと思う
Linuxの場合はプロセス単位のmmap_semという、仮想アドレスの伸長をロックするロックが
あるのでもう少し遅い
プロセス単位でmmap関連はジャイアントロックがある感じなんですね
たぶん、他のOSでも仮想アドレスが伸びるときはロックとってると思う
Bug#905JRubyの実装がヘボいだけなんだから、そっち直せと返事した

一方FreeBSDでは

http://svn.freebsd.org/viewvc/base/head/lib/libc/stdlib/malloc.c?revision=204493&view=markup
なんか中でmremap相当のことをしているような気もするがよくわからん
コピーコストが効いてくるのは、でかい文字列のときなので huge_ralloc() が愚直にhuge_malloc()してmemcpyしてるのが効いてくると思う
僕はFreeBSDを普段使ってないので鵜呑みにするのは危険だけど
あぁ、ここか
うん、小さいstringだと、どのみちカーネルでなんとか出来る可能性はないんですよ。最小処理単位がページサイズなので
むしろ小さい文字列の方が real issue だと思うのです

提案をする前に

しかし、なにか提案をしようという人は howto-persuade-matz-rubykaigi2008.pdf を読むべきだと思います。

絵文字変換表生成の高速化

生成が遅いので高速化しようという話。絵文字が遅いのは実は valid_encoding と nomap_table の衝突が原因らしい。これは GB18030 が遅いのとは別の理由な模様。

SQLRails

SQL の JIS 化に関する委員会の資料を見つけたんだけど
http://www.jsa.or.jp/stdz/instac/syoukai/H19_houkoku/h19annual-report/01_09.pdf
市場動向調査の最初に Ruby on Rails が出てきててビックリした

前に Java に注目した時は、SQL/OLB とかを作ったらしいです。今度はなにをするんでしょうかね。

kosaki 先生の git 講座 その 3 くらい

git revert

よし、revert だ
特定のコミットを revert するのってどうやるんだろう
git revert [commit-id]
git log でcommit id さがす
ChangeLog とかどうなるんだろう
ええと、gitだとsubversion式の履歴から完全に消すことはできないので
revert = 逆コミットがここで入ったと普通のログに残る
たんに、サブジェクトが Revert hogehoge となっているだけ
revert したと ChangeLog に書けない?
そういうことがしたいなら、1) git revert する 2) ChangeLogを編集 3) git commit --amend -av あたりでrevertとChangeLog変更を統合
難しい

衝突したとき

git はなんというか、UNIXのコマンドと一緒で定石おぼえるまでがツライ
何か間違えたときに元の状態に戻しにくい
git checkout -f でよいのでは?
あと、git reflogでいままでの操作の履歴が残っているので好きなところにUNDOできるよ
衝突状態になったときとか良く意味不明になる
うん、あれはUIがよくないと思う。衝突したときはミスしがちだから、-f つけないときは無理矢理続行できないというポリシーはただしいのだが
-f というのを知った
1) git statusして、衝突しているファイルを確認 2) ファイルを編集 3) git add と僕はやってる
それすれば衝突とかも全部無視して checkout した状態に戻せる?
git add したらコミットしてしまいそうで怖い
git checkout -f はリボジトリの強制チェックアウトで自分の加えた変更が全部消える。 git reset --hard も同じく消える
衝突状態というのがどこに保存されているか見えにくいのである
僕もあまりよく分かってない。git add するまで衝突が解除されないように見える

git commit -v

あとはアレです。git commit するときに常に -v オプションつけるのをオススメします。これで patch description書く画面で、下の方で commit されるパッチが表示されるのでコミットミスが劇的に減る
それに、最後に自分で自分のパッチをレビューするのは良い習慣だし
それはやってます
がーそ
mameさん、あなたに教える事はもうなにもありません。免許皆伝じゃ(T_T

configure のオプション

rdocの生成うざい
なんとかdisableできないものか
--disable-install-doc

ちなみにわたしは ./configure --enable-shared --without-tk --disable-install-doc --with-opt-dir=/usr/local warnflags='-Wall -pedantic -Wno-long-long -Wno-overlength-strings' --prefix=/home/naruse/local/ruby_1_9 とか設定している