View diff from current version
平内です。 Java屋でした。Javaの言語以外の部分が好きだった。いい夢見させてもらったなぁ。 * hogeとワタシ - Schemeとワタシ -- 2000年頃、Scheme本を読んで「こいつぁ一生つきあえる言語だ!」と確信する。 -- 実用に足る処理系を探しつつ、Scheme(Lisp)本を買いあさる。 -- Gaucheを見て「こいつは一生つきあえる処理系かも?」と思う。 -- ヒマが手に入ったので、一気にSchemeをモノにしようと修行に励んでいる。 - Javaとワタシ -- 2番目に読んだ技術書が「Java言語入門 ローラ・リメイ著」(初めて読んだ技術書?は「コの業界のオキテ」) -- 初めてプログラマーとして入った会社が、組込JavaOSを作ってるアツい所だった。 -- Javaには色々文句あるけど、他人にJavaの悪口を言われると、つい凹でしまう。 - プログラミングとワタシ -- ゲーム作りたいなー。じゃあ、プログラマーになるか。という訳でなったらしい。 -- ゲーム製作は人工知能を組むところで挫折。Schemeをモノにしたら再開しよう。 * portapi実験場 今日はportapi.cの宿題を片付けようと、一日中Makefileをイジクリまわしていた。 結局./libgauche_*.dllを最適化戦略の数だけ作り、./gosh -ftest io_bench.scmする前に./libgauche.dllにmvすることにした。 {{{ text data bss dec hex filename 463508 62132 37584 563224 89818 libgauche_0.dll 464052 62132 37584 563768 89a38 libgauche_0i.dll 474132 62132 37584 573848 8c198 libgauche_org.dll ------------------------------------------------------------------------------- arc i686-pc-cygwin thread-type none strategy real user system process 0 35.01 12.99 19.46 32.46 #全体をSAFE_CALLで囲む 0i 41.37 12.54 25.73 38.27 #全体をSAFE_CALLで囲む(インライン展開) org 34.20 11.84 19.61 31.45 #オリジナル }}} インライン展開がこんなに遅いとは。。。なんでやろ?(2004/03/05 07:24:27 PST) - [[Shiro]]: CVS版はポートロックの度にsigprocmaskを呼ばないように なっています。結構差が出るみたいなんで、それを加味して試してみて 下さい。src/gauche/vm.hだけ直しても差が出るかも。 - [[hira]]: やってみました。体感速度が上がりましたね。適用前のと比べると、userがちょい増えて、systemが激減。0iの遅さはsystemの機嫌次第で、0と互角だったり激重だったりと不安定だったけど、これで安定したっぽい。 {{{ #sigprocmaskを呼ばない版 text data bss dec hex filename 463188 62196 37584 562968 89718 libgauche_0.dll 464084 62196 37584 563864 89a98 libgauche_0i.dll 473972 62196 37584 573752 8c138 libgauche_org.dll ------------------------------------------------------------------------------- arc i686-pc-cygwin thread-type none strategy real user system process 0 29.28 13.93 13.71 27.65 #全体をSAFE_CALLで囲む 0i 29.85 14.73 13.09 27.82 #全体をSAFE_CALLで囲む(インライン展開) org 27.30 13.04 12.24 25.29 #オリジナル }}} - [[hira]]: やっぱりsigprocmaskは必要っぽいです。 make testしたときに、systemのテストから返ってこなくなっちゃいました。 {{{ Testing system ... }}} Cygwinの場合、下のようなエラーが出るはずなんですが。 {{{ Testing system ... failed. discrepancies found. Errors are: test normalize: expects "/cygdrive/d/home/abc" => got "/cygdrive/d/home/win/abc" test sigalrm1: expects 14 => got 0 }}} - [[Shiro]]: どこで止まったかわかります? (test.logの最後を見てください)。(2004/03/06 18:26:41 PST) - [[hira]]: ココで止まってました。 {{{ test fork & sigint, expects #t ==> }}} そうそう。固まってからは、Ctrl-Cを連発してもビクともしないんです。無敵状態なのでコンソールを落とすしかない。 [[hira]]:「1. SAFE_CALLの前にportタイプで分岐する(Scm_<port-type>_Putbを呼ぶ)」が完成。早速ベンチをとってみました。 {{{ #sigprocmaskを呼ぶ版 text data bss dec hex filename 462804 62196 37584 562584 89598 libgauche_0.dll 463668 62196 37584 563448 898f8 libgauche_0i.dll 468308 62196 37584 568088 8ab18 libgauche_1.dll 473908 62196 37584 573688 8c0f8 libgauche_1i.dll 474292 62196 37584 574072 8c278 libgauche_org.dll ------------------------------------------------------------------------------- arc i686-pc-cygwin thread-type none strategy real user system process 0 21.95 11.17 9.532 20.70 #全体をSAFE_CALLで囲む 0i 22.87 11.92 9.498 21.42 #全体をSAFE_CALLで囲む(インライン展開) 1 21.75 10.67 9.222 19.89 #SAFE_CALLの前にportタイプで分岐する 1i 21.50 10.21 9.5 19.71 #SAFE_CALLの前にportタイプで分岐する(インライン展開) org 20.59 9.972 9.562 19.53 #オリジナル }}} スピードは0 < 1 < orgですね。あと、インライン展開無しのほうが速い傾向にあります。 全体的に、かなり速度が上がってますが、原因不明です。テストはちゃんと通ってるのですが。4日ぶりにOSをリブートしたのが効いたのかしら。 [[hira]]:「2. 全面的にScm_MakeVirtualPortを採用してみる」を作ろうとしたけど、設計してみたら、結構大変なことになった。 portapiに依存しているソースも修正しないといかん。 gauche.hのマクロも修正だし。 ※FdはFile, Socket, Stdin/out/errの親クラスという位置づけ。 {{{ struct ScmPortRec { /* 省略 */ union { /* 省略 */ //これは廃止して以下に展開する //ScmPortVTable vt; /* virtual port */ } src; /* portapi interface. */ /* safe */ int (*Getb)(ScmPort *p); int (*Getc)(ScmPort *p); int (*Getz)(char *buf, int buflen, ScmPort *p); //ScmObj (*Getline)(ScmPort *p); int (*ByteReady)(ScmPort *p); int (*CharReady)(ScmPort *p); int (*Putb)(ScmByte b, ScmPort *p); int (*Putc)(ScmChar c, ScmPort *p); int (*Putz)(const char *buf, int len, ScmPort *p); int (*Puts)(ScmString *s, ScmPort *p); int (*Flush)(ScmPort *p); int (*Close)(ScmPort *p); off_t (*Seek)(ScmPort *p, off_t off, int whence); /* unsafe */ int (*GetbUnsafe)(ScmPort *p); int (*GetcUnsafe)(ScmPort *p); int (*GetzUnsafe)(char *buf, int buflen, ScmPort *p); //ScmObj (*GetlineUnsafe)(ScmPort *p); int (*ByteReadyUnsafe)(ScmPort *p); int (*CharReadyUnsafe)(ScmPort *p); int (*PutbUnsafe)(ScmByte b, ScmPort *p); int (*PutcUnsafe)(ScmChar c, ScmPort *p); int (*PutzUnsafe)(const char *buf, int len, ScmPort *p); int (*PutsUnsafe)(ScmString *s, ScmPort *p); int (*FlushUnsafe)(ScmPort *p); int (*CloseUnsafe)(ScmPort *p); off_t (*SeekUnsafe)(ScmPort *p, off_t off, int whence); }; /* portapi implements */ /*Scm_<TYPE><METHOD><ENCODE><UNSAFE>*/ /*Getb*/ Scm_FdGetb Scm_IStrGetb /*Getc*/ Scm_FdGetcEUC Scm_FdGetcSJIS Scm_FdGetcUTF8 Scm_IStrGetcEUC Scm_IStrGetcSJIS Scm_IStrGetcUTF8 /*Getz*/ Scm_FdGetz Scm_IStrGetz /*Getline*/ //エンコードの扱いが難しい。フィルタにて提供か? エンコード毎に提供するか? /*CharReady*/ Scm_FdCharReady Scm_IStrCharReady /*ByteReady*/ Scm_FdByteReady Scm_IStrByteReady /*Putb*/ Scm_FdPutb Scm_OStrPutb /*Putc*/ Scm_FdPutcEUC Scm_FdPutcSJIS Scm_FdPutcUTF8 Scm_OStrPutcEUC Scm_OStrPutcSJIS Scm_OStrPutcUTF8 /*Putz*/ Scm_FdPutz Scm_OStrPutz /*Flush*/ Scm_FdFlush /*Close*/ Scm_FdClose /*Seek*/ Scm_FileSeek Scm_IStrSeek Scm_OStrSeek /*あとFdのUnsafe系とnull系(すでにある)*/ }}} interfaceとimplementsのバインドはポート生成時に行う。 これが上手くいくと次の2つが手に入る。 - ポートの動的エンコーディング(encodingはポート作成時に決定する): せっかく関数ポインタなんだからと、欲張ってみた。 でもstring,regexp,symbolのエンコーディングは静的のまま。 string,regexpもエンコードの数だけ用意するか、マクロではなく関数呼び出しでよしとするか。 -- [[Shiro]]: 「動的エンコーディング」というのは何を指していますか。 外部リソースがネイティブエンコーディングと違うなら、どっちにせよ エンコーディングのためだけに一段バッファが必要(読み書きするバッファは 別に必要)なので、メカニズム的には現在のgauche.charconvと大差ないと 思うのですが。 -- [[hira]]: うん。これは変なこと考えてたと思います。 - (たぶん)保守しやすいソース -- [[Shiro]]: あ、それと、portは外部への入出力だけでなく、 文字列ポートとして内部での処理に多用されることに注意して下さい。 Gaucheは文字列ポートにかなり依存しています。従って、文字列ポートの 作成と読み書きは軽くなければなりません。 -- [[hira]]: 了解です。オリジナルより速くするのはかなり大変だと思いますが、速度5%落ちだけど、その他のおまけが色々付いてくる、という線を狙ってます。 以下の問題を解決するものではない。 - soft-portのgetb, getc,getzのどれかひとつを提供すれば、他はGaucheが提供してあげる: これは単純に体力勝負か。 個人的には、ポートを新しく作らせるより、フィルタを作らせたいのだけど。 -- [[Shiro]]: 性能的にペナルティが無ければ、そっちの方がいいです。 - 「バッファになりえるもの」の抽象化: これ、実はよく分かってないんですよね。 srcに対するアクセスを抽象化したい、ということでしょうか? Fd内の問題としてOKなのかなぁ。mmapもfdが無いと始まらないし。 I/OStrも「バッファになりえるもの」としてくくろうとしてます? エンコーディング問題をココで一挙に解決しようとか? -- [[Shiro]]: fdは関係なくて、現在のread-blockとread-block!のように、 calleeでバッファをアロケートする場合とcallerでバッファを与える場合を どう綺麗にハンドリングするかという話です。read-block!はuvectorを バッファとして渡してますが、これを「バッファになり得るもの」という 抽象クラスで括れないかと思って。uvectorを使うとdlopenするuvector.so に依存してしまうので、コアのlibgauche.so内に書きにくいんです。 -- [[hira]]: ああ、どうもです。ようやく理解できました。 ---- * ビックリ事件 2,3日前、sort!の「破壊的に再利用」の意味を誤解してハマったことがあった。 MLを読み返していたら[http://lists.sourceforge.jp/mailman/archives/gauche-devel-jp/2003-January/000077.html 似たような話]が出てきたのでsort!だけじゃ無いのかとビックリした。 しかし、どうにも分かりにくい。なんでだろ。 {{{ 1. 元の値も戻り値も使用したい。(副作用なし) 2. 元の値を使用したい。(set!しなおす手間を省きたい。メモリを節約したい) 3. 戻り値を使用したい。(メモリを節約したい) }}} 1と2の感覚しか持ち合わせていなかった、ということか。 2は束縛への副作用を目的としているのだけど、3では束縛への副作用は効率化のための手段に過ぎない。 副作用の有無だけでなく、2と3の違いが見た目で分かるようにならないかなぁ。3は「!!」にするとか。 sort, sort!!, remove, remove!!となっていればこんなハマり方しなくて済むのだけれど。。。(2004/03/07 06:32:50 PST) - [[hira]]:これはリストならではの問題か。vectorに「!!」はありえないんだよなぁ。コレクションとしてlistとvectorを同一視出来ないってのは、やっぱりビックリだ。と思ったら、gauche.collection には「!」系が無かった。・・・この辺はあとで整理しておこう。R5RS,SRFI,gauche.collectionとRuby,Javaなどのコレクションとの比較だな。(2004/03/07 17:40:28 PST) - [[Shiro]]: まとめましょう→[[Scheme:!と?]] * 思い込んだら、試練の道 久しぶりに「switch文のbreak忘れバグ」にハマった。これとtypoは私の天敵だ。簡単に半日は持っていかれる。 自分は正しい、と思い込んでるため、疑惑があさっての方向に向かってしまうからだ。 困難なバグの場合、それに喰らいついて解決したら「俺ってすごいぜ!」と満足感が味わえるものだが、 typoを半日かけて解決した日にゃ「俺ってアホだぜ。。。」とがっかりするしかない。 ま、年に一度のイベントだと思えばいいか。今年はもう無いだろう。(2004/03/06 17:30:21 PST) * 論よりRun 今日はportapi.cの宿題を片付けようと、一日中Makefileをイジクリまわしていた。 結局./libgauche_*.dllを最適化戦略の数だけ作り、./gosh -ftest io_bench.scmする前に./libgauche.dllにmvすることにした。 {{{ text data bss dec hex filename 463508 62132 37584 563224 89818 libgauche_0.dll 464052 62132 37584 563768 89a38 libgauche_0i.dll 474132 62132 37584 573848 8c198 libgauche_org.dll ------------------------------------------------------------------------------- arc i686-pc-cygwin thread-type none strategy real user system process 0 35.01 12.99 19.46 32.46 #全体をSAFE_CALLで囲む 0i 41.37 12.54 25.73 38.27 #全体をSAFE_CALLで囲む(インライン展開) org 34.20 11.84 19.61 31.45 #オリジナル }}} インライン展開がこんなに遅いとは。。。なんでやろ?(2004/03/05 07:24:27 PST) * 何も出力しないマクロが欲しい 気兼ねなくデバッグログを埋め込みたいので、何も出力しないマクロが欲しい。 {{{ (define-syntax p (syntax-rules () ((_ msg ...) (print "***p***>" msg ... )))) (define-syntax p (syntax-rules () ((_ msg ...) ))) ;コレがやりたいんだけどsyntax errorになる (define-syntax p (syntax-rules () ((_ msg ...) () ))) ;仕方ないからコレでガマン (begin (p 'a)(p 'a)(p 'a)(p 'a)) ;(1) (begin) ;(2) }}} (1)と(2)が同じ意味になるようなマクロって定義できないのだろうか。(2004/03/04 06:17:31 PST) - [[Shiro]] (2004/03/04 07:04:42 PST): R5RS的には(begin)は未定義で、 Gaucheの現在のふるまいも「たまたまそう動いている」というものにすぎません。 ただ、もし余分な () がシーケンスの途中に入ることによる性能低下を 気にしているのでしたら心配御無用、値が使われないリテラルは コンパイル時に消えます。(tail positionにあったら消えませんが、 その場合はデバッグマクロの有り無しで戻り値が違ってしまいますね)。 - [[hira]] (2004/03/04 14:01:57 PST): おお、それなら性能低下を気にせずにすみますね。 ちなみにtail positionではこんなの使ってます。 {{{ (define-syntax pp (syntax-rules () ((_ val msg ...) (let1 result val (print "***pp**>" msg ... " :val<" result ">") result)))) }}} 性能が低下するなら、ppしか使えないなぁと心配してたんですが、取り越し苦労でした。 - [[Shiro]]: valが多値になる場合に御注意。 * coroutine = subroutineだと思ってたあの頃 coroutineて書き言葉を見るまで、自分の勘違いに気付かなかった。 Kahuaセミナー聞いてた時もこんなだったし↓ {{{ 「コルーチン」などはcall/ccの例として、ほげほげふがふがどうのこうの・・・ ↓ 「子ルーチン」 ↓ 「サブルーチン」 ↓ (゚Д゚)ハァ? oO(call/ccって謎だなー) }}} 過去にどれだけ「コルーチン」という言葉を見聞きしたか、記憶をたぐるのが恐ろしい。 (2004/03/03 07:37:21 PST) * クラスの中に入りたい slotにprivateなアクセッサを定義しようとして、あれ?っと思いました。 generic functionでディスパッチということは、自他の区別なんて無いのかと。 moduleのimport/exportが近いけど、staticな変数の可視/不可視の制御なので、ちょっと違う。 slotにpublic/privateの概念を持ち込むにはどうすればいいのだろう? クラスの中に入る仕組みがあれば良いのだろうけど。 そうすれば、slot-refにイライラしなくても済むっていうオマケも付くのだが。 (2004/03/02 07:42:32 PST) {{{ (slot-ref self 'hoge) ;;21文字 CLOS:フツーの書き方 this.getHoge() //14文字 Java:thisマニアが自己カプセル化したときの書き方 hoge ;; 4文字 CLOS/Java:私が望む書き方 }}} - [[Shiro]]: これは興味深いテーマなので、移動しましょう→ [[Gauche:スロットアクセス]]