Before when I forgot the signature of procedures, I always search the internet (usually these procedures were defined in R6RS). However Sagittarius has a document which contains R6RS procedures as well. Why didn't I use it? It's because searching the internet was usually faster than open the document HTML and look it up.
And now, I thought this is inconvenient. (It was!). So I made a library called (sagittarius interactive support) which provides a macro 'document'. This macro look up given name from the document. For this purpose, from 0.3.4 document will be located in the install path.
Then I have also noticed, it was really pain in the ass to type '(import (sagittarius interactive support)' each time when I run the REPL. So I added initialisation file '.sashrc' loading to REPL. REPL will search the file from either $HOME or $USERPROFILE and if it found, then load the contents to the REPL environment.
Now it's a bit more convenient.
Syntax highlighter
2012-06-27
2012-06-24
(lambda ())
What should this expression return?
According R6RS and R7RS (draft 6), lambda form must have at least one expression. So I guess this must be syntax error. (I could not find explicit sentence said raise an error, neither R6RS nor R7RS draft).
So, I checked some implementations, Gauche, Ypsilon, mosh, chibi-scheme, guile and Sagittarius.
The implementations raised syntax error: mosh, chibi-scheme, guile.
I guess these are strict for syntax.
Gauche returned a procedure which returns 0 or unspecified value, depending on how you defined.
Ypsilon returned a procedure which returns unspecified value.
The funniest behaviour was actually mine. It returned procedure which returns itself. This expression was valid;
According R6RS and R7RS (draft 6), lambda form must have at least one expression. So I guess this must be syntax error. (I could not find explicit sentence said raise an error, neither R6RS nor R7RS draft).
So, I checked some implementations, Gauche, Ypsilon, mosh, chibi-scheme, guile and Sagittarius.
The implementations raised syntax error: mosh, chibi-scheme, guile.
I guess these are strict for syntax.
Gauche returned a procedure which returns 0 or unspecified value, depending on how you defined.
Ypsilon returned a procedure which returns unspecified value.
The funniest behaviour was actually mine. It returned procedure which returns itself. This expression was valid;
(define (test)) (((test))) ;; #<closure test>But don't try this expression, it will abort with out of memory;
(((lambda ()))) ;; abort or never returnI guess this must be either syntax error or returning unspecified value.
Githubのアカウントを作ってみた
Mercurialに慣れていて、Gitは構ったこと無かったんだけど、Googleコードですごく小さなリポジトリを作るのに気が退けてなんとなくGithub。
Githubはチュートリアル充実してるなぁというイメージだった。Googleコードはどうだったかなぁ?難しくは無かった記憶だけど、Mercurial自体の使い方は自力で調べた気がする。
とりあえず、Twitter用のAPIライブラリをどこかに置きたかったので作っただけ。気が向いたら使ってやってください。
Sagittarius-net-twitter
そういえば、作るつもりないってどこかで言ったような気がする。2ヶ月くらい前に・・・あの時は本当に無かったんだ。
Githubはチュートリアル充実してるなぁというイメージだった。Googleコードはどうだったかなぁ?難しくは無かった記憶だけど、Mercurial自体の使い方は自力で調べた気がする。
とりあえず、Twitter用のAPIライブラリをどこかに置きたかったので作っただけ。気が向いたら使ってやってください。
Sagittarius-net-twitter
そういえば、作るつもりないってどこかで言ったような気がする。2ヶ月くらい前に・・・あの時は本当に無かったんだ。
2012-06-23
正規表現
#/(?:aa?){n}a{n}/という正規表現(nは任意の数)がどれくらい遅くなるかをチェックしようとしたら正規表現のコンパイラがエラーを飛ばした。ソースを見ると特にコメントも無く、
/* ugh, ugly */
とだけある。(よくこういうのを書く。)問題はこう書いてあるということは何らかの問題があってそうせざるを得なかったはずなのだが、思い出せない。とりあえず、必要そうに見えないのでコメントアウトしてコンパイル。テストも全部通る。なんだったんだろう?問題が見つかったら考えることにしよう。こういうことが多々あるのだから、コメントは都度書くようにしないとなぁ。やっつけで直してコメント書かないことが多いから・・・(仕事ではそれを反面教師にしているのかまじめに書いてる)
っで、件の速度チェック。 ここを見て、Sagittariusではどうなるんだろう?と実験してみたかった。
これどうやってたんだっけな (正規表現・続々) - Island Life
見た感じO(n)の正規表現エンジンの方が使われるはずだからSagittariusではO(n^2)にはならないはずだけど、と思いつつ以下のコードで実験。
っで以下が結果。
/* ugh, ugly */
とだけある。(よくこういうのを書く。)問題はこう書いてあるということは何らかの問題があってそうせざるを得なかったはずなのだが、思い出せない。とりあえず、必要そうに見えないのでコメントアウトしてコンパイル。テストも全部通る。なんだったんだろう?問題が見つかったら考えることにしよう。こういうことが多々あるのだから、コメントは都度書くようにしないとなぁ。やっつけで直してコメント書かないことが多いから・・・(仕事ではそれを反面教師にしているのかまじめに書いてる)
っで、件の速度チェック。 ここを見て、Sagittariusではどうなるんだろう?と実験してみたかった。
これどうやってたんだっけな (正規表現・続々) - Island Life
見た感じO(n)の正規表現エンジンの方が使われるはずだからSagittariusではO(n^2)にはならないはずだけど、と思いつつ以下のコードで実験。
#< (sagittarius regex) >
(import (rnrs) (sagittarius regex) (srfi :42) (time)
(sagittarius control))
;;(use srfi-42)
(define s (apply string (list-ec (: x 100) #\a)))
(print ((#/(?:aa?){40}a{40}/ s) 0))
(time
(dotimes (i 100)
(#/(?:aa?){40}a{40}/ s)))
いい加減、毎回正規表現のリーダーマクロを有効にするのが面倒だが、ライブラリをインポートしないと正規表現自体使えないからなぁ・・・っで以下が結果。
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ;; 0.125000 real 0.125000 user 0.000000 sys普通。単発で走らせた結果が、0.014くらいだったのでリニアだろう。単純な正規表現ならO(n)が保障されているのはそれなりに強みだろう。(エンジン自体が遅いので、微妙だけど・・・)
Lisp
声優ユニットではない。(違ったっけ?名前だけで見たことないから)
ふと昨日のレーベンシュタイン距離の実装でScheme(というかSagittarius)では速度が出ないので、バイナリ吐けるSBCLで書き直した時に思ったこと。(そのうちLisp版のコードも貼り付けよう。汚いけど)
Lispという言葉を知ったのは大学3年の研究室配属の際に教官の一人がLispを使った何かの研究をしていたというのが最初だろうか。ちょっと調べて括弧だらけな上に、リストとか繋げてなにが出来るんだよこれ?みたいな感想しかない上に、研究内容も面白くなさそうだから別の研究室に行った。
っで、配属された研究室の教官がemacs使いでWindows版emacsとしてxyzzyを使っていた。xyzzyはまぁ、有名なCommon Lisp版emacsでもちろん拡張Lisp入れまくりになった。その際に自分でも書けたら便利じゃね?とか思って中身を見たけど、書ける気がしなくて挫折した記憶がある。
それからもずっとxyzzyを使ってはいたけど、時は流れて2009年某BlogでSICPなるものを知りオランダに来たばかりで職探しに困難を極めていたのでスキルアップも兼ねてSchemeをさわり始めた。Javaの仕事探してるのにSchemeなんてというのもあったが、基本的なアルゴリズムとかはなにやっても一緒だと思っていた。
っで、なにを思ったのか自分の処理系を作り始めた。これは職が見つかってから。ずいぶんSchemeにも慣れて仕事で使うスクリプトをSchemeで書きたいと思ったけど、既存の処理系には暗号関係のライブラリがあんまりなかったので(今思えばRacketとかChickenにはあったかも)、じゃあ作るかと思い立ったのが最初。もちろん、思い立ったらできるわけはなく、実際に鍵が作れるとか、X.509の証明書が読めるとかまで3年かかっている。今思えばGaucheで拡張ライブラリ書いた方がよかった気もするが、まぁいいか。
っで、ついこの間SBCLと速度勝負をした際に、ほぼ初めてCommon Lispのソースを書いた気がする。(もちろん読むということはしていた)。今まで、「なんでもありのCLに手を出したら、Schemeが窮屈に感じるかもしれない」と思って敬遠していた。必死になってCで書いたコードでたたき出した速度をLispであっさり実現できるというのは正直かなりショックだった。ただ、速度が欲しい処理にはLispで書けばいいかと思えるようになった。もちろん、そんな処理に出会うことなどほとんどないだろうと思っていた。
と思っていたんだけど、昨日のレーベンシュタイン距離である。ちょっとバイナリ吐けないと厳しいなぁと思いSBCLで書いてみた。 単にSchemeからCLへの移植なのだが、同じ機能でもCLの方がいろんなものが標準で揃っている分書きやすいなぁという印象だった。マクロとか、パッケージとか込み入ったものは全然使っていないので、実際はそうでもないのかもしれないが。(loopマクロとかずるいよね。手続き型言語的な感覚で書ける。)
Lisperになる(なれる?)気はあんまりしないんだけど、選択肢が増えるのはいいことだと思う。と自分に言い聞かせる。
追記:
nilが'()であり#fであるというのは結構便利だと思った。デザイン的には首をかしげるところだけど、実用的には便利。
ふと昨日のレーベンシュタイン距離の実装でScheme(というかSagittarius)では速度が出ないので、バイナリ吐けるSBCLで書き直した時に思ったこと。(そのうちLisp版のコードも貼り付けよう。汚いけど)
Lispという言葉を知ったのは大学3年の研究室配属の際に教官の一人がLispを使った何かの研究をしていたというのが最初だろうか。ちょっと調べて括弧だらけな上に、リストとか繋げてなにが出来るんだよこれ?みたいな感想しかない上に、研究内容も面白くなさそうだから別の研究室に行った。
っで、配属された研究室の教官がemacs使いでWindows版emacsとしてxyzzyを使っていた。xyzzyはまぁ、有名なCommon Lisp版emacsでもちろん拡張Lisp入れまくりになった。その際に自分でも書けたら便利じゃね?とか思って中身を見たけど、書ける気がしなくて挫折した記憶がある。
それからもずっとxyzzyを使ってはいたけど、時は流れて2009年某BlogでSICPなるものを知りオランダに来たばかりで職探しに困難を極めていたのでスキルアップも兼ねてSchemeをさわり始めた。Javaの仕事探してるのにSchemeなんてというのもあったが、基本的なアルゴリズムとかはなにやっても一緒だと思っていた。
っで、なにを思ったのか自分の処理系を作り始めた。これは職が見つかってから。ずいぶんSchemeにも慣れて仕事で使うスクリプトをSchemeで書きたいと思ったけど、既存の処理系には暗号関係のライブラリがあんまりなかったので(今思えばRacketとかChickenにはあったかも)、じゃあ作るかと思い立ったのが最初。もちろん、思い立ったらできるわけはなく、実際に鍵が作れるとか、X.509の証明書が読めるとかまで3年かかっている。今思えばGaucheで拡張ライブラリ書いた方がよかった気もするが、まぁいいか。
っで、ついこの間SBCLと速度勝負をした際に、ほぼ初めてCommon Lispのソースを書いた気がする。(もちろん読むということはしていた)。今まで、「なんでもありのCLに手を出したら、Schemeが窮屈に感じるかもしれない」と思って敬遠していた。必死になってCで書いたコードでたたき出した速度をLispであっさり実現できるというのは正直かなりショックだった。ただ、速度が欲しい処理にはLispで書けばいいかと思えるようになった。もちろん、そんな処理に出会うことなどほとんどないだろうと思っていた。
と思っていたんだけど、昨日のレーベンシュタイン距離である。ちょっとバイナリ吐けないと厳しいなぁと思いSBCLで書いてみた。 単にSchemeからCLへの移植なのだが、同じ機能でもCLの方がいろんなものが標準で揃っている分書きやすいなぁという印象だった。マクロとか、パッケージとか込み入ったものは全然使っていないので、実際はそうでもないのかもしれないが。(loopマクロとかずるいよね。手続き型言語的な感覚で書ける。)
Lisperになる(なれる?)気はあんまりしないんだけど、選択肢が増えるのはいいことだと思う。と自分に言い聞かせる。
追記:
nilが'()であり#fであるというのは結構便利だと思った。デザイン的には首をかしげるところだけど、実用的には便利。
2012-06-22
レーベンシュタイン距離
某求職掲示板で見つけたパズル。あわよくば答えつけて応募してやろうと思ったのだが、かなりハードルが高い。
問題はレーベンシュタイン距離が1の単語のネットワークを計算するというもの。レーベンシュタイン距離自体を求める処理は以下のように書ける。
レーベンシュタイン距離を求めるアルゴリズムはO(mn)で、距離が1の物を自前で見つけるよりは速いと思うんだけど、問題なのはネットワークを構成するのに使用される単語リストが26万くらいあること。とりあえず与えられた単語をリストから順番に見ていくようにしたのだが、世代が4を超えた辺りで計算オーダーがとんでもないことになるっぽく、ちょっと現実的な時間で帰って来ない。(10分とかでは無理)。
根本的にO(n^m)になるような気がするのだけど、(nが単語リストでmが与えられた単語)、これに更に世代が入ってくるとげんなりするよなぁ。第一世代のmは一個だけど、二世代目以降は複数になるわけだし。なんか、別な方法があるのだろうか?
問題はレーベンシュタイン距離が1の単語のネットワークを計算するというもの。レーベンシュタイン距離自体を求める処理は以下のように書ける。
(define (levenshtein-distance word1 word2)
(define (table-ref t i j)
(vector-ref (vector-ref t i) j))
(define (table-set! t i j v)
(vector-set! (vector-ref t i) j v))
(define (make-table word1 word2)
(let1 table (make-vector (+ (string-length word1) 1) 0)
(dotimes (i (+ (string-length word1) 1))
(vector-set! table i (make-vector (+ (string-length word2) 1) 0)))
(dotimes (i (string-length word1))
(table-set! table (+ i 1) 0 (+ i 1)))
(dotimes (i (string-length word2))
(table-set! table 0 (+ i 1) (+ i 1)))
table))
(let ((d (make-table word1 word2))
(word1-size (string-length word1))
(word2-size (string-length word2)))
(dotimes (i word1-size)
(dotimes (j word2-size)
(if (char=? (string-ref word1 i) (string-ref word2 j))
(table-set! d (+ i 1) (+ j 1) (table-ref d i j))
(table-set! d (+ i 1) (+ j 1)
(min (+ (table-ref d i (+ j 1)) 1)
(+ (table-ref d (+ i 1) j) 1)
(+ (table-ref d i j) 1))))))
(table-ref d word1-size word2-size)))
普通にWikipediaに載っていたものをSchemeで書き直しただけ。メモリのアロケーションを気にして2次元配列を1次元で表現したバージョンも作ったんだけど、Sagittariusでは普通に書いた方がわずかに速かったので却下した。なんでだろう?レーベンシュタイン距離を求めるアルゴリズムはO(mn)で、距離が1の物を自前で見つけるよりは速いと思うんだけど、問題なのはネットワークを構成するのに使用される単語リストが26万くらいあること。とりあえず与えられた単語をリストから順番に見ていくようにしたのだが、世代が4を超えた辺りで計算オーダーがとんでもないことになるっぽく、ちょっと現実的な時間で帰って来ない。(10分とかでは無理)。
根本的にO(n^m)になるような気がするのだけど、(nが単語リストでmが与えられた単語)、これに更に世代が入ってくるとげんなりするよなぁ。第一世代のmは一個だけど、二世代目以降は複数になるわけだし。なんか、別な方法があるのだろうか?
2012-06-21
apply argument limit
It was yesterday evening I was considering that values might have to be implemented not to allocate any memory such as mosh or Gauche. (well, currently values returns first class object named values too).
Then I wrote test code like this;
The problem is really simple. Sagittarius' compiler compiles apply procedure as a builtin instruction APPLY. This instruction pushes given arguments to stack, however it does not check whether or not stack overflows and current maximum stack size is 10000.Yes, it breaks something I don't want to.
The solution can be 2 ways. The easiest way is check arguments count and if it's more than maximum then raises an error. The not so easy way is change the behaviour of APPLY a bit.
The first one is a bit awkward even if nobody applies such huge number of arguments. So I will do the latter one.
I don't know when I can say it's stable...
Then I wrote test code like this;
(import (rnrs) (srfi :42)) (apply values (list-ec (: x 150000) (* x x)))Well, it just applies a list contains 150000 elements to values. I don't know why I put such a huge number but it revealed a bug in Sagittarius. (could be mosh as well).
The problem is really simple. Sagittarius' compiler compiles apply procedure as a builtin instruction APPLY. This instruction pushes given arguments to stack, however it does not check whether or not stack overflows and current maximum stack size is 10000.Yes, it breaks something I don't want to.
The solution can be 2 ways. The easiest way is check arguments count and if it's more than maximum then raises an error. The not so easy way is change the behaviour of APPLY a bit.
The first one is a bit awkward even if nobody applies such huge number of arguments. So I will do the latter one.
I don't know when I can say it's stable...
2012-06-19
(net twitter)
なんてライブラリを作成中。(というか、あとドキュメントだけ)。これだけ特異化されているライブラリを処理系本体に入れるつもりは全然なくて、別パッケージにする予定。(そのために突貫で作ったものがあるし)
一応XMLとJSON両方サポートしてるけど、JSONの方を使う気がしない。というか、自分では仕事してる振りしながらコマンドラインで呟くくらいしかしなさそう・・・
肝になる部分ってOAuthなのでひたすらTwitterのAPI見て実装するだけという結構疲れる作業であった。
しかし、今更感が拭えないなぁ。まぁ、いいか。
一応XMLとJSON両方サポートしてるけど、JSONの方を使う気がしない。というか、自分では仕事してる振りしながらコマンドラインで呟くくらいしかしなさそう・・・
肝になる部分ってOAuthなのでひたすらTwitterのAPI見て実装するだけという結構疲れる作業であった。
しかし、今更感が拭えないなぁ。まぁ、いいか。
2012-06-18
Sagittarius 0.3.3 リリース
Sagittarius Scheme 0.3.3がリリースされました。
今回のリリースはメンテナンスリリースです。
修正された不具合
今回のリリースはメンテナンスリリースです。
修正された不具合
- sjis、euc-jpコーデックがASCIIコードを認識できない不具合が修正されました。
- string portによる改行コードの読み取り不具合が修正されました。
- stringを扱う手続きが'\0'をうまく読み取らない不具合が修正されました。
- Unicode周りの不具合が大幅に修正されました。
- bytevector->string系の手続きがEOLにLFを使っていた不具合が修正されました。
- Transcoder周りの不具合が修正されました。
- string->symbolが特定の場面においておかしなシンボルを返す不具合が修正されました。
- リテラルリストが変更可能な不具合が修正されました。
- (srfi :14 char-set)ライブラリにunbound variableが含まれている不具合が修正されました。
- PKCS EMSAエンコード及びMGF-1手続きの実装が間違っていたのが修正されました。
- csv-readが複数コメント行を読み取れない不具合が修正されました。
- object-applyが追加されました。
- pointer-c-ref-pointer及び、decrefが(sagittarius ffi)に追加されました。
- OAuthライブラリにサービスプロバイダ機能が追加されました。
- 正規表現ライブラリに便利なマクロが追加されました。
- unwind-protectが(sagittarius control)に追加されました。
- map、for-each、fold-left及びfold-rightが末尾再帰になるよう実装しなおされました。
- (clos user)ライブラリで提供されているマクロがsyntax-caseで実装しなおされました。
- bytevector->integer及びinteger->bytevectorの性能が改善されました。
- out-of-treeビルドが可能になりました。
- (www cgi)ライブラリが追加されました。
- (www fastcgi)ライブラリが追加されました。
- (text html-lite)ライブラリが追加されました。
- (text tree)ライブラリが追加されました。
- (rfc :5322)ライブラリがドキュメント化されました。
- (rfc base64)ライブラリがドキュメント化されました。
- (rfc quoted-printable)ライブラリがドキュメント化されました。
- (packrat)ライブラリがドキュメント化されました。
- (json)ライブラリがドキュメント化されました。
- (text csv)ライブラリがドキュメント化されました。
Sagittarius vs SBCL その2
さすがにワード単位での比較(というか、機能が違うものの比較)はおかしいだろうと思い、SBCL限定で動くbytevector->integerをまじめに実装してみた。以下がコード。
オリジナルも動作がおかしかったので多少修正。(Bignumに入れる順番が逆だった)。
Sagittariusのベンチマークは以前と一緒。環境はUbuntu (Virtual BOX)。バージョンは忘れた。確認方法も忘れたorz
っで、結果:
同じ機能がSBCLより速かったという事実だけで十分です。
タイトルが「vc」になっていたので修正。
(defun u64vector->integer (bvec)
(declare (optimize (safety 0) (speed 3) (debug 0)))
(let* ((len (length bvec))
(ans (sb-bignum:%allocate-bignum len)))
(loop :for e :of-type (unsigned-byte 64) :across bvec
:for i :of-type fixnum :from 0
:do (sb-bignum:%bignum-set ans (- len i 1) e))
ans))
(defvar u64 (make-array 25 :initial-contents
(loop :for i :of-type fixnum :from 0 :to 24 :collect i)))
(time (dotimes (i 100000)
(u64vector->integer u64)))
(defvar *sbcl-bignum-element-size* 8)
(defun bytevector->integer (bvec)
(declare (optimize (safety 0) (speed 3) (debug 0)))
(let* ((len (length bvec))
(bignum-size (ceiling (/ len *sbcl-bignum-element-size*)))
(ans (sb-bignum:%allocate-bignum bignum-size)))
(loop :for i :of-type fixnum :from 0 :to bignum-size
:do (let ((e 0)
(pos (- len 1 (* i *sbcl-bignum-element-size*))))
;; FIXME the size must be calculated by element size
(declare (type (unsigned-byte 64) e))
(loop :for j :of-type fixnum :from 0 :to *sbcl-bignum-element-size*
:do (unless (< (- pos j) 0)
(setf e (+ e (ash (aref bvec (- pos j))
(ash j 3))))))
(sb-bignum:%bignum-set ans i e)))
ans))
(defvar bv (make-array 100 :initial-contents
(loop :for i :of-type fixnum :from 0 :to 99 :collect i)))
(time (dotimes (i 100000)
(bytevector->integer bv)))
基本的にはSagittariusで実装しているやり方と一緒。(もっとうまいやり方があれば教えてください。)オリジナルも動作がおかしかったので多少修正。(Bignumに入れる順番が逆だった)。
Sagittariusのベンチマークは以前と一緒。環境はUbuntu (Virtual BOX)。バージョンは忘れた。確認方法も忘れたorz
っで、結果:
~/build$ sbcl --script bv-int.lisp Evaluation took: 0.023 seconds of real time 0.024001 seconds of total run time (0.024001 user, 0.000000 system) 104.35% CPU 76,849,374 processor cycles 10,399,624 bytes consed Evaluation took: 0.595 seconds of real time 0.596037 seconds of total run time (0.596037 user, 0.000000 system) [ Run times consist of 0.004 seconds GC time, and 0.593 seconds non-GC time. ] 100.17% CPU 1,935,858,048 processor cycles 304,000,848 bytes consed ~/build$ sash bv-int.scm ;; 0.034603 real 0.032002 user 0.000000 sysあ、確かにSBCLのbytevector->integerの方が10倍遅い。多分、ashがまずいんじゃないかな、と勝手に推測。bvecがfixnumのベクタだと宣言できて、ashの結果がbignumにならないことが宣言できればもう少し速くなる気がするけど、そこまでは面倒なのでやらない。
同じ機能がSBCLより速かったという事実だけで十分です。
タイトルが「vc」になっていたので修正。
2012-06-17
Sagittarius vs SBCL
My ubuntu does not have Japanese input environment, so I need to write it in English. I need to install something later but that's not the topic for now.
The previous topic I mentioned SBCL implementation of bytevector->integer and it said Sagittarius was faster then SBCL. And I thought it was because of the machine spec that I took the improvement benchmark. So now, my question is 'Is Sagittarius really faster than SBCL?'
Conclusion first, SBCL was faster. Then how much faster is it?
The benchmark result is this.
OK, here comes my excuse. The CL one is not actually for bytevector but for u64 vector. The author told me, vector access for word size is faster than octet size, so u64 size is the fastest code and other must have one or more loops to construct bignum. And he also told me, if he add one more loop, it became 10 times slower (I tried but my CL skill was not good enough to implement it).
On the other hand, Sagittarius does construct bignum from bytevector so that it has nested loops inside. If the author was correct, then Sagittarius is faster than SBCL. Well, I know this is just dreaming...
Could someone provide the code? I want to test.
I tested with my own implementation of bytevector->integer on SBCL and Sagittarius was actually 10 times faster. For more details, see this page (in Japanese)
The previous topic I mentioned SBCL implementation of bytevector->integer and it said Sagittarius was faster then SBCL. And I thought it was because of the machine spec that I took the improvement benchmark. So now, my question is 'Is Sagittarius really faster than SBCL?'
Conclusion first, SBCL was faster. Then how much faster is it?
The benchmark result is this.
~/projects/build$ sbcl --script test.lisp Evaluation took: 0.036 seconds of real time 0.036003 seconds of total run time (0.032002 user, 0.004001 system) 100.00% CPU 105,786,338 processor cycles 5,600,520 bytes consed ~/projects/build$ sash test.scm ;; 0.075894 real 0.072005 user 0.004000 sysThe used code is the same as my bytevector->integer topic and the one on gist. (So it was actually not the same data and might be a bit advantaged for SBCL. Because compiler can optimise the embedded array.)
OK, here comes my excuse. The CL one is not actually for bytevector but for u64 vector. The author told me, vector access for word size is faster than octet size, so u64 size is the fastest code and other must have one or more loops to construct bignum. And he also told me, if he add one more loop, it became 10 times slower (I tried but my CL skill was not good enough to implement it).
On the other hand, Sagittarius does construct bignum from bytevector so that it has nested loops inside. If the author was correct, then Sagittarius is faster than SBCL. Well, I know this is just dreaming...
I tested with my own implementation of bytevector->integer on SBCL and Sagittarius was actually 10 times faster. For more details, see this page (in Japanese)
integer->bytevector
前回の手続きの逆である。折角bytevector->integerを高速化したんだし、逆もベンチマークとって見るかとやってみた。以下がコード。
どこまでいってもポイントとしては無駄なアロケーションを避けるという点と、直接Bignumの演算をするのではなく、構成しているlongの値だけで計算するというもの。これで、Cのプリミティブなビット演算だけで片付く。
っで、結果:
(import (time) (sagittarius control))
(define bv (do ((i 0 (+ i 1)) (bv (make-bytevector 100 0)))
((= i 100) bv)
(bytevector-u8-set! bv i i)))
(define n (bytevector->integer bv))
(define count 100000)
(time (dotimes (i count)
(integer->bytevector n)))
っで、結果:
$ sash test.scm ;; 5.609375 real 5.515000 user 0.016000 sys #| Core Duo 1.66GHz |#もちろん、前回と同じ理由で遅い。ということで、Fixnumの場合とBignumの場合で分ける。
どこまでいってもポイントとしては無駄なアロケーションを避けるという点と、直接Bignumの演算をするのではなく、構成しているlongの値だけで計算するというもの。これで、Cのプリミティブなビット演算だけで片付く。
っで、結果:
$ ./build/sash.exe test.scm ;; 0.156250 real 0.156000 user 0.000000 sys環境はもちろん一緒。50倍くらい速い。とはいっても、この辺りの処理は単発で使われることの方が多いので、ベンチマーク用ともいえる。
CLで、bytevector->integerみたいなのを作ってみたけど、こんなに速くできない。 fixnumの範囲で計算して、後で合体ってのが一番速いだろうか: 時の羅針盤@blog: bytevector->integer 【 compassoftime.blogspot.jp/2012/06/byteve… 】
— ⠗⠐⠥ ⠵⠱⠊⠷さん (@g000001) 6月 14, 2012
これを見て調子の乗ってやった。反省はしていない。
2012-06-14
bytevector->integer
かなりの頻度でこの手続きを使うなぁと思い、適当にパフォーマンスを計測。
100バイトのbytevectorを100000回ほど変換してみた。
コード:
与えられたbytevectorのサイズを見ればfixnumの範囲なのか、bignumが必要なのかは分かる。また、どれだけのサイズのbignumが必要なのかも分かる。ということで、その辺を考慮してゴリゴリと書き換えた。
結果として、メモリのアロケーションはbignum作成時のみの最大1回に抑えられている。どれほどパフォーマンスに影響を与えるか試してみた。コードは同じもの。
結果。
これでcrypto周りのスピードが改善される(はず)。
100バイトのbytevectorを100000回ほど変換してみた。
コード:
(import (time) (sagittarius control))
(define bv (do ((i 0 (+ i 1)) (bv (make-bytevector 100 0)))
((= i 100) bv)
(bytevector-u8-set! bv i i)))
(define count 100000)
(time (dotimes (i count)
(bytevector->integer bv)))
結果。% sash test1.scm ;; 3.245882 real 4.336000 user 0.453000 sys高速ではないね。現状の実装では、与えられたbytevectorを地味にビットシフトして足しているので、値がbignumになると余計なアロケーションが走る。せっかくC側で実装しているのだし、ちょっと最適化。
与えられたbytevectorのサイズを見ればfixnumの範囲なのか、bignumが必要なのかは分かる。また、どれだけのサイズのbignumが必要なのかも分かる。ということで、その辺を考慮してゴリゴリと書き換えた。
結果として、メモリのアロケーションはbignum作成時のみの最大1回に抑えられている。どれほどパフォーマンスに影響を与えるか試してみた。コードは同じもの。
結果。
% ./build/sash test1.scm ;; 0.027005 real 0.015000 user 0.000000 sys圧倒的じゃないか、わが軍は。(違ったっけ?)
これでcrypto周りのスピードが改善される(はず)。
2012-06-12
必要に駆られて
Sagittariusに拡張ライブラリをインストール可能にしようという話。
なんとなく必要に駆られてきたのでそれっぽいのを作った。Gaucheのgauche-packageに似せたけど機能はしょぼしょぼ、インストールとかはCMakeまかせというやる気の無い仕様。
Twitterに呟くのとかを別プロジェクトにして、どこかに置きたいという理由だけ。
作ってる最中に間違って/usr/local/shareを消してしまい(Cygwin上)、(util file)が(math)に依存しているという致命的な不具合を見つけた。(ビルド時に動的にコードを生成しているので、作成されていないライブラリに依存するとビルドがこける)。この辺のライブラリ依存関係をいい加減何とかしないとなぁ。
とりあえず、0.3.3に入る予定。多分明文化はしばらくしない。
なんとなく必要に駆られてきたのでそれっぽいのを作った。Gaucheのgauche-packageに似せたけど機能はしょぼしょぼ、インストールとかはCMakeまかせというやる気の無い仕様。
Twitterに呟くのとかを別プロジェクトにして、どこかに置きたいという理由だけ。
作ってる最中に間違って/usr/local/shareを消してしまい(Cygwin上)、(util file)が(math)に依存しているという致命的な不具合を見つけた。(ビルド時に動的にコードを生成しているので、作成されていないライブラリに依存するとビルドがこける)。この辺のライブラリ依存関係をいい加減何とかしないとなぁ。
とりあえず、0.3.3に入る予定。多分明文化はしばらくしない。
2012-06-07
JScript sucks!
I have been working for 2 days for IE specific bug. And I could not even reproduce it on my usual environment such as IE8 or IE9 on Windows 7 or Windows XP. The platform I could only see it was Windows Server 2003 with IE 8.
Until now, I still couldn't figure out how I can solve it and couldn't find any article about this bug either. So let me memorise what happened and what was different between working environment and incorrect environment.
Before starting explanation, let me describe the background environment. We are using Wicket on the server and some process requires AjaxRequestTarget which is created Wicket's internal request cycle depending on the browsers request of course. And the problem was somehow browser did not request with AJAX but usual GET request in this case just click the link.
The problem seemed javascript did not work properly on 'A' tag's 'onclick attribute. It did not report any error but just processed 'href' value instead of 'onclick' javascript. First I thought this is IE8 specific bug if 'A' tag has both 'href' and 'onclick' then it process both and 'href' will be the latter so that browser send non AJAX request to server and die.
As I already mentioned the usual client environments work very fine, but on Windows Server 2003. So I made the test environment and tried to debug with IE8's ugly javascript debugger. First I added following code to 'onclick' attribute; 'alert(this)'. Then it suddenly raised error said 'JScript runtime error: Object required'. And from there if I delete the line it also raised error unless I refresh the page. So it seemed 'this' object was incorrect. However it is just 'A' tag itself how could it be wrong? (NOTE: we are using JQuery and in onclick $('') function was called.)
Now, at least I have one hint, alert message I added to the attribute. It said 'javascript:void(0)' means the same value as 'href' had. I'm not JScript expert but as far as I know usual IE showed 'Object' or something not 'href's value. This looked really weird to me. So I check the JScript engine's version both working and non working environment. Yes, the version was not the same. On working environment which is using IE 9 had version 5.8.16982 however non working environment had 5.8.23141! I have no idea if this is specific version for Windows Servers but smelled crappy as hell.
So I copied jscript.dll from server to XP on VM and see what happened. Unfortunately it wasn't the case. Not the version different of JScript engine but platform dependency? I'm stuck. So we concluded don't use Windows Server as a client.
If you know what is wrong and how we can solve it, PLEASE let me know.
Until now, I still couldn't figure out how I can solve it and couldn't find any article about this bug either. So let me memorise what happened and what was different between working environment and incorrect environment.
Before starting explanation, let me describe the background environment. We are using Wicket on the server and some process requires AjaxRequestTarget which is created Wicket's internal request cycle depending on the browsers request of course. And the problem was somehow browser did not request with AJAX but usual GET request in this case just click the link.
The problem seemed javascript did not work properly on 'A' tag's 'onclick attribute. It did not report any error but just processed 'href' value instead of 'onclick' javascript. First I thought this is IE8 specific bug if 'A' tag has both 'href' and 'onclick' then it process both and 'href' will be the latter so that browser send non AJAX request to server and die.
As I already mentioned the usual client environments work very fine, but on Windows Server 2003. So I made the test environment and tried to debug with IE8's ugly javascript debugger. First I added following code to 'onclick' attribute; 'alert(this)'. Then it suddenly raised error said 'JScript runtime error: Object required'. And from there if I delete the line it also raised error unless I refresh the page. So it seemed 'this' object was incorrect. However it is just 'A' tag itself how could it be wrong? (NOTE: we are using JQuery and in onclick $('') function was called.)
Now, at least I have one hint, alert message I added to the attribute. It said 'javascript:void(0)' means the same value as 'href' had. I'm not JScript expert but as far as I know usual IE showed 'Object' or something not 'href's value. This looked really weird to me. So I check the JScript engine's version both working and non working environment. Yes, the version was not the same. On working environment which is using IE 9 had version 5.8.16982 however non working environment had 5.8.23141! I have no idea if this is specific version for Windows Servers but smelled crappy as hell.
So I copied jscript.dll from server to XP on VM and see what happened. Unfortunately it wasn't the case. Not the version different of JScript engine but platform dependency? I'm stuck. So we concluded don't use Windows Server as a client.
If you know what is wrong and how we can solve it, PLEASE let me know.
2012-06-01
rotate left
さすがに落ちたかな、ちと課題が難しかった・・・
電話とネットコードシェアみたいなサービスをつかったインタビューを受けていた。課題はメモリアロケーションをしないリストの回転。いろいろ考えて大分力尽きた感じであった。さすがに残念である。
っで、 そのまま放っておくのももったいないと思い、調べてみたりした。
std::rotate を読んでみた - d.v.d
C++のSTLにはそのようなアルゴリズムがあるらしく、上記のサイトに解説があった。ということでSchemeで写経。swap部分は適当。
入れ替え、入れ替えでいけるよなぁとか考えてたけど違う路線で考えていた。基本的なアルゴリズムの知識が足りない。
あきら~めまっしょお~、あきらめまっしょお~♪
電話とネットコードシェアみたいなサービスをつかったインタビューを受けていた。課題はメモリアロケーションをしないリストの回転。いろいろ考えて大分力尽きた感じであった。さすがに残念である。
っで、 そのまま放っておくのももったいないと思い、調べてみたりした。
std::rotate を読んでみた - d.v.d
C++のSTLにはそのようなアルゴリズムがあるらしく、上記のサイトに解説があった。ということでSchemeで写経。swap部分は適当。
(define (rotete-left vec m)
(define (itr s m e)
(if (or (= s m) (= e m))
vec
(let loop ((s s) (mm m))
(if (or (= s m) (= mm e))
(if (= s m)
(itr s mm e)
(itr s m e))
(let ((v1 (vector-ref vec s))
(v2 (vector-ref vec mm)))
(vector-set! vec s v2)
(vector-set! vec mm v1)
(loop (+ s 1) (+ mm 1)))))))
(let ((len (vector-length vec)))
(itr 0 m len)))
なにをやっているか分かるし、知っていれば直ぐに解けるんだろうなぁとは思うけど、正直知らなきゃ無理って感じのものだ。特に30分とかで解けるようなものではないと信じたい。凡才では閃かないよこんなの・・・入れ替え、入れ替えでいけるよなぁとか考えてたけど違う路線で考えていた。基本的なアルゴリズムの知識が足りない。
あきら~めまっしょお~、あきらめまっしょお~♪
2012-05-29
DONT_ADD_BYTE_AT_END
Yes, it's GC again. For some reason, GC_size did not return proper (means I wanted) value for pair pointer. It always returns 16 bytes instead of 8. I needed to figure it out why?
So I started to read Boehm GC's source code again. GC_size just returns header's size and the size is defined before allocation. So it must be in GC_init. (Well, it wasn't this easy to find out, first I needed to know how gran size came and so on...). In GC_init, there was a function named GC_init_size_map, ah, this is it.
So I stepped into the function and figured it out what's going on. Well, it's just calculating the gran size with extra byte. Now I have got other problem, how can I remove this without rebuilding gc library? GC_set_all_interior_pointer causes other problem. So far, I can't see any solution. Hmm...
So I started to read Boehm GC's source code again. GC_size just returns header's size and the size is defined before allocation. So it must be in GC_init. (Well, it wasn't this easy to find out, first I needed to know how gran size came and so on...). In GC_init, there was a function named GC_init_size_map, ah, this is it.
So I stepped into the function and figured it out what's going on. Well, it's just calculating the gran size with extra byte. Now I have got other problem, how can I remove this without rebuilding gc library? GC_set_all_interior_pointer causes other problem. So far, I can't see any solution. Hmm...
2012-05-24
How to use FastCGI on Apache2 on Cygwin
I wanted to run FastCGI on Cygwin Apache2 server and I could not find specific article for it. If there is no documentation, then I would be the first one;)
So, the first step is downloading mod_fcgi from http://httpd.apache.org/mod_fcgid/. You can easily find the source code form the link 'your local mirror'.
Then next step is compiling and installing. I believe this step is the most difficult step to find a clue. Well, just the linker problem actually. The following command you need to run. And make sure you have all related Cygwin modules, such as libapr-1 and libuuid-devel.
Now, it's time to configure the httpd.conf.
Add this line after your final line of LoadModule
When you finish it, then run Apache2. Before run it, make sure your cygserver is running otherwise Cygwin complains.
You can see the environment variables if it successfully installed. Enjoy.
So, the first step is downloading mod_fcgi from http://httpd.apache.org/mod_fcgid/. You can easily find the source code form the link 'your local mirror'.
Then next step is compiling and installing. I believe this step is the most difficult step to find a clue. Well, just the linker problem actually. The following command you need to run. And make sure you have all related Cygwin modules, such as libapr-1 and libuuid-devel.
$ APXS=/usr/sbin/apxs2 ./configure.apxs $ make LDFLAGS="-lapr-1 -laprutil-1 -lhttpd" $ make installThe point is LDFLAGS. Somehow created Makefile does not contain the necessary libraries.
Now, it's time to configure the httpd.conf.
Add this line after your final line of LoadModule
LoadModule fcgid_module lib/apache2/mod_fcgid.soAnd put a file end with
.conf extension in conf.d directory. Then add this configuration in the file.
<Directory /home/*/public_html/fcgi-bin/> SetHandler fcgid-script Options +ExecCGI </Directory>I assume you are using the userdir_module.
When you finish it, then run Apache2. Before run it, make sure your cygserver is running otherwise Cygwin complains.
$ /usr/sbin/cygserver & $ CYGWIN=server /usr/sbin/apachectl2 startOK, let's test. Put this script into the directory 'fcgi-bin' in your public_html directory named hello.cgi.
#!/usr/bin/perl
use CGI::Fast;
while (my $q = CGI::Fast->new) {
print("Content-Type: text/plain\n\n");
foreach $var (sort(keys(%ENV))) {
$val = $ENV{$var};
$val =~ s|\n|\\n|g;
$val =~ s|"|\\"|g;
print "${var}=\"${val}\"\n";
}
}
Make sure you have FCGI module in your platform. Then access http://locahost/~username/fcgi-bin/hello.cgiYou can see the environment variables if it successfully installed. Enjoy.
2012-05-22
CLOSのqualifierで遊んでみる
前にも書いたような気がするが、まぁいいか。
とりあえず、組み込みのprint関数の呼び出し前に与えられた引数をエラーポートに出力したいとする。ここではprintにしたけど、別に何でもいい。
そうすると、こう書ける。
なにが嬉しいか?Aspect指向的なことが簡単に出来そう。(多分前にも書いたな)。とりあえずこれを使って何か出来ないか考えたい。問題は、通常の呼び出しに比べて遅いことか・・・
とりあえず、組み込みのprint関数の呼び出し前に与えられた引数をエラーポートに出力したいとする。ここではprintにしたけど、別に何でもいい。
そうすると、こう書ける。
(import (rnrs) (clos user)) (define org:print print) (define-method print objs (apply org:print objs)) (define-method print ((num <integer>) . args) (format #t "~b" num) (apply print args)) (define-method print :before args (display args (current-error-port)) (newline (current-error-port))) (print 1 2 3) #| (1 2 3) ;; これらがエラーポートに出力された引数 (2 3) ;; printが呼ばれた回数だけ:beforeが呼ばれている (3) () ;; もちろん'()もある 11011 |#ついでに、先頭の引数が数字だったら2進数で出力するようにしてある。意味はない。オリジナルの名前を変えているのはqualifierがどのパターンでも適用されるようにするため。単にオリジナルと同じ引数を取る総称関数がほしいだけともいう。
なにが嬉しいか?Aspect指向的なことが簡単に出来そう。(多分前にも書いたな)。とりあえずこれを使って何か出来ないか考えたい。問題は、通常の呼び出しに比べて遅いことか・・・
2012-05-20
Transcoderがバッファを持つとこうなる
BOM関連のバグを直していて気づいた。Transcoderは状態もバッファも持ってはいけないということに。
以下が端的な不具合再現コード。
すると、2度目のlookahead-charのBOMチェックになって、ごにょごにょ。(詳しく理解してないorz)
コードを修正、最初にBOMチェックをさせてからバッファに溜め込まないと意味がない。
Transcoderはあくまで単なるプロセスでないとまずいはずので、 バッファ自体はポートが持つべきである。直す。
以下が端的な不具合再現コード。
(import (rnrs)) (define tr (make-transcoder (utf-16-codec))) (call-with-port (open-file-input-port "utf16file.txt" (file-options) 'block tr) (lambda (in) (display (get-char in))(display (lookahead-char in)) (newline))) (call-with-port (open-file-input-port "utf16file2.txt" (file-options) 'block tr) (lambda (in) (display (get-char in))(display (lookahead-char in)) (newline)))ファイルはUTF-16である必要は無いんだけど、このコードで、2つ目のcall-with-portは変な値を返す。なぜか、Transcoderが最初にlookahead-charで読んだ文字をバッファに溜め込んでいるので、2度目はバッファから返してくる。
コードを修正、最初にBOMチェックをさせてからバッファに溜め込まないと意味がない。
Moshにパッチを送った。
Moshにバグレポートしたら「時間が無いからパッチを送って」みたいなニュアンスでコメントが付いたので送ったった。僕も誰かからパッチを送ってほしいよ。こっちは開発人員一人だっつ~の!
っで、よく考えてみたらパッチの作り方とか全然知らないので、どうするのか調べてみた。以下のサイトが非常に分かりやすかった。(というか、まんま使い方)
パッチの作り方と当て方はこうするもんね - 檜山正幸のキマイラ飼育記
当てたパッチは、MoshのIssue 232にまるっと貼り付けた。githubのアカウントなんて持ってないし・・・賞味時間半の大作業であったw
しかし、MoshはCygwin上でテスト走らせると結構こける。これは僕のパッチが問題ではなく、もともとこけるみたい。 test/print.scmのテストは0.2.7では2テストこけて、そこでmake checkが終了する。メインのターゲットではないのだろうが、もう少しCygwinユーザをいたわってほしいものだ。
運がよければパッチが採用されて、いつリリースされるか分からない0.2.8でBOM周りのチェックが改善されているはず。
Sagittariusの初期の頃いろいろコードを参考にさせてもらったので、まぁ恩返し。
っで、よく考えてみたらパッチの作り方とか全然知らないので、どうするのか調べてみた。以下のサイトが非常に分かりやすかった。(というか、まんま使い方)
パッチの作り方と当て方はこうするもんね - 檜山正幸のキマイラ飼育記
当てたパッチは、MoshのIssue 232にまるっと貼り付けた。githubのアカウントなんて持ってないし・・・賞味時間半の大作業であったw
しかし、MoshはCygwin上でテスト走らせると結構こける。これは僕のパッチが問題ではなく、もともとこけるみたい。 test/print.scmのテストは0.2.7では2テストこけて、そこでmake checkが終了する。メインのターゲットではないのだろうが、もう少しCygwinユーザをいたわってほしいものだ。
運がよければパッチが採用されて、いつリリースされるか分からない0.2.8でBOM周りのチェックが改善されているはず。
Sagittariusの初期の頃いろいろコードを参考にさせてもらったので、まぁ恩返し。
2012-05-19
Unicode変換処理の実行時間差
Larcenyのベンチマークにbv2stringという処理がある。名前の通りバイトベクターからストリングに変換する処理である。普通の処理と違うのは、これがあほかというくらい繰り返す点であろう。最近Transcoder周りを改善したのでちょっとチャレンジしてみた。
っで、標題の件である。この処理については意外なことにYpsilonが苦手としている。逆にSagittariusはかなり高速に処理をする。(moshはもっと速いんだけど、出てくる結果が不正確)。以下はbv2stringの中から抜粋して上記3つの処理系で速度を計ってみた結果。
moshが最速なのだが、結果が不正確である。実際string=?の部分を出力するとUTF-8のテストで#fが返っている。 (これはbv2stringの一部なのでUTF-8だけなのだが、全部を走らせると鬼のように不正確な値を返す。恐らくUTF-16及びUTF-32に変換した後のチェックが省かれているのだろう)。
Sagittariusは実用的な速度で正確な結果を返す。ただし、開発版である。0.3.2以前は不正確な値を返す。これはmoshの項で記載したチェックが省かれていたため。
以外だったのはYpsilonである。今まで異次元の速さを誇っていたのがここにきて異次元の遅さになってしまっている。 Ypsilonのutf16->string、string->utf16、utf32->string及びstring->utf32はSchemeで実装されているのでそれが原因かと思ったのだが、utf8->stringとstring->utf8も遅かった。(ちなみに、この2つはC++で実装されている。見間違えていなければ)。ここからは推測になるのだが、これは内部エンコーディングの差ではないだろうか?moshとSagittariusは内部で文字列をUCS4で持っているが、Ypsilonはutf-8で持っている。なので、bv -> ucs4 -> utf8と2回変換が走ることになって、その分のオーバーヘッドが処理時間に如実に反映されているのではないだろうか?
なにはともあれ、一つでもYpsilonに勝ったと言える部分があるのは嬉しいことである。
っで、標題の件である。この処理については意外なことにYpsilonが苦手としている。逆にSagittariusはかなり高速に処理をする。(moshはもっと速いんだけど、出てくる結果が不正確)。以下はbv2stringの中から抜粋して上記3つの処理系で速度を計ってみた結果。
(import (rnrs) (rnrs mutable-strings))
(define (test-char-range name lo hi tostring tobytevector)
(let* ((n (+ 1 (- hi lo)))
(s (make-string n))
(replacement-character (integer->char #xfffd)))
(do ((i lo (+ i 1)))
((> i hi))
(let ((c (if (or (<= 0 i #xd7ff)
(<= #xe000 i #x10ffff))
(integer->char i)
replacement-character)))
(string-set! s (- i lo) c)))
(string=? (tostring (tobytevector s)) s)))
(define (test-exhaustively name tostring tobytevector)
(test-char-range name #x10000 #x1ffff tostring tobytevector))
(test-exhaustively "UTF-8" utf8->string string->utf8)
(test-exhaustively "UTF-16"
(lambda (bv) (utf16->string bv 'big))
string->utf16)
(test-exhaustively "UTF-32"
(lambda (bv) (utf32->string bv 'big))
string->utf32)
$ time sash test.scm
sash test.scm 0.73s user 0.12s system 94% cpu 0.906 total
$ time mosh test.scm
GC Warning: Repeated allocation of very large block (appr. size 524288):
May lead to memory leak and poor performance.
mosh test.scm 0.52s user 0.12s system 97% cpu 0.656 total
$ time Ypsilon test.scm
Ypsilon test.scm 0.01s user 0.06s system 0% cpu 1:49.86 total
YpsilonはWindows版をCygwin上で走らせているのでトータルのタイムのみが出ている点に注意。moshが最速なのだが、結果が不正確である。実際string=?の部分を出力するとUTF-8のテストで#fが返っている。 (これはbv2stringの一部なのでUTF-8だけなのだが、全部を走らせると鬼のように不正確な値を返す。恐らくUTF-16及びUTF-32に変換した後のチェックが省かれているのだろう)。
Sagittariusは実用的な速度で正確な結果を返す。ただし、開発版である。0.3.2以前は不正確な値を返す。これはmoshの項で記載したチェックが省かれていたため。
以外だったのはYpsilonである。今まで異次元の速さを誇っていたのがここにきて異次元の遅さになってしまっている。 Ypsilonのutf16->string、string->utf16、utf32->string及びstring->utf32はSchemeで実装されているのでそれが原因かと思ったのだが、utf8->stringとstring->utf8も遅かった。(ちなみに、この2つはC++で実装されている。見間違えていなければ)。ここからは推測になるのだが、これは内部エンコーディングの差ではないだろうか?moshとSagittariusは内部で文字列をUCS4で持っているが、Ypsilonはutf-8で持っている。なので、bv -> ucs4 -> utf8と2回変換が走ることになって、その分のオーバーヘッドが処理時間に如実に反映されているのではないだろうか?
なにはともあれ、一つでもYpsilonに勝ったと言える部分があるのは嬉しいことである。
2012-05-18
Unicode対応
Larcenyのベンチマークを走らせようとしているのだが、リーダーや走らせるたびに文字コード周りでテストが失敗する。よくも悪くもかなり厳しくテストが作られているようだ。(正直、リーダー周りは処理系が#!r6rsを付けた際にR6RSに準拠することを前提に作られているので結構厳しかった。)
Unicode周りはそんなに厳密に作っていなかったので、結構な修正を迫られた。おかげでかなり厳密にエンコード、デコードするようになった(と思う)。
UTF32やUTF16に関しては単に範囲のチェックを入れるだけだったのだが、UTF8が結構問題だった。
マルチバイト文字列というのは最初の途中のバイトが不正バイトでも、最初の1バイトのみを不正として扱わないといけないというのにはまった。まぁ、言われてみればそうだよなぁとは納得するのだが、読み取った数バイトをポートに戻すということが出来ないので、ポートから1バイトずつ読み込む場合は不正バイトを検出しても戻らないという糞仕様で回避。(Ypsilonも戻ってないように見えるし、ファイルを読み込むときはいいよね、ファイルを信用しても?)
utf8->stringみたいなすでにバッファに取ってあるバイトのみ不正バイトを検出するようにして、とりあえずベンチマークが要求する部分は解決した。
ただ、このベンチマーク、走らせる条件も厳しいけど、要求してる速度も厳しい。特にCygwinは相手にしてないみたいで、(というか、R6RSの処理系の多くはCygwin対応してない気がする)、一気に1M以上メモリを割り当ててみたり、テスト回数が5桁からだったりとセットで走らせるとしばらく応答がないということがしばしば。
これがあんまり待つことなくさくさく動いたら、多分最速の処理系だろうなぁ。とりあえずはmoshと速度比較かなぁ。
Unicode周りはそんなに厳密に作っていなかったので、結構な修正を迫られた。おかげでかなり厳密にエンコード、デコードするようになった(と思う)。
UTF32やUTF16に関しては単に範囲のチェックを入れるだけだったのだが、UTF8が結構問題だった。
マルチバイト文字列というのは最初の途中のバイトが不正バイトでも、最初の1バイトのみを不正として扱わないといけないというのにはまった。まぁ、言われてみればそうだよなぁとは納得するのだが、読み取った数バイトをポートに戻すということが出来ないので、ポートから1バイトずつ読み込む場合は不正バイトを検出しても戻らないという糞仕様で回避。(Ypsilonも戻ってないように見えるし、ファイルを読み込むときはいいよね、ファイルを信用しても?)
utf8->stringみたいなすでにバッファに取ってあるバイトのみ不正バイトを検出するようにして、とりあえずベンチマークが要求する部分は解決した。
ただ、このベンチマーク、走らせる条件も厳しいけど、要求してる速度も厳しい。特にCygwinは相手にしてないみたいで、(というか、R6RSの処理系の多くはCygwin対応してない気がする)、一気に1M以上メモリを割り当ててみたり、テスト回数が5桁からだったりとセットで走らせるとしばらく応答がないということがしばしば。
これがあんまり待つことなくさくさく動いたら、多分最速の処理系だろうなぁ。とりあえずはmoshと速度比較かなぁ。
2012-05-17
Transcoderを改善したいのその2
書き出し側は昨日やったので今日は読み込み側。とりあえずUTF8だけで実装してみた。
検証コード:
ちなみに、上記のコードでblockをnoneに変更したら最速になった。というか、他の処理系が2倍程度遅くなって、Sagittariusの速度は変わらないだけ。
もう少し気になる点として、バイトベクタのポートにするとあほかと思うほど遅くなるんだけど、なんでだろう?それでも、0.3.2よりは速いので、今までどんだけ遅かったんだということにはなるのだが・・・
検証コード:
(import (rnrs) (time))
(define times 10000)
(define test-data
(string->utf8 "12345678901235678901234567890123456790123456789\r\n"))
(define tr (make-transcoder (utf-8-codec) 'crlf))
(time
(do ((i 0 (+ 1 i)))
((= i times) (display times)(newline))
(let ((in #;(transcoded-port (open-bytevector-input-port test-data) tr)
(open-file-input-port "test.scm" (file-options no-fail) 'block tr)))
(get-string-n in 100)
(close-input-port in)))
)
実行結果:0.3.2、開発版の順。
$ time sash test.scm 10000 ;; 7.765625 real 3.734000 user 3.235000 sys sash test.scm 3.98s user 3.41s system 88% cpu 8.391 total $ time ./build/sash.exe test.scm 10000 ;; 4.062500 real 1.359000 user 2.235000 sys ./build/sash.exe test.scm 1.61s user 2.44s system 86% cpu 4.688 total $ time Ypsilon test.scm 10000 ;; 5.015625 real 0.65625 user 3.9375 sys Ypsilon test.scm 0.03s user 0.06s system 1% cpu 5.312 totalおよそ倍くらい速い。Ypsilonより多少速い。ただ、IOに関してはmoshが一番速かった。上記の検証コードの(time)を(mosh)に変更してmoshで実行。
$ time mosh test.scm 10000 ;;3.765625 real 1.2029999999999998 user 2.265 sys mosh test.scm 1.36s user 2.45s system 90% cpu 4.219 totalsystem時間はそんなに変わらないので計算に掛かっている時間の差なのだが、変換の処理自体にそんなに差はないと思うんだけどなぁ?moshのIOは遅いというのをどこかで見たのだが、嘘だったのだろうか?
ちなみに、上記のコードでblockをnoneに変更したら最速になった。というか、他の処理系が2倍程度遅くなって、Sagittariusの速度は変わらないだけ。
もう少し気になる点として、バイトベクタのポートにするとあほかと思うほど遅くなるんだけど、なんでだろう?それでも、0.3.2よりは速いので、今までどんだけ遅かったんだということにはなるのだが・・・
2012-05-16
Transcoderを改善したい
普通に使っているとテキストファイルのIOなんて(なぜか)そう使わないので気にならなかったのだが、httpsとか普通のhttpとかで一文字ずつ変換して流してると無駄だよなぁと思いはじめてきた。
とりあえずどれくらい違うのか試してみたいなぁと思い、utf8コーデック+put-stringだけの変更という形でベンチマーク。
ベンチーマークに使ったコードは以下。
とりあえずどれくらい違うのか試してみたいなぁと思い、utf8コーデック+put-stringだけの変更という形でベンチマーク。
ベンチーマークに使ったコードは以下。
(import (rnrs) (time) (sagittarius control))
(define times 10000)
(define test-string "12345678901235678901234567890123456790123456789\r\n")
(define tr (make-transcoder (utf-8-codec) 'crlf))
(time
(let ((out (open-file-output-port "tmp.txt" (file-options no-fail) 'block tr)))
(dotimes (i times)
(put-string out test-string))
(close-output-port out)))
これを0.3.2と開発版で比較。
結果は以下。
% ./build/sash.exe test.scm ;; 0.013002 real 0.016000 user 0.000000 sys % sash test.scm ;; 0.312032 real 0.141000 user 0.172000 sys上が開発版。びっくりするほど違う。これはやる価値ありだな。とりあえずやることにする。
Sagittarius version 0.3.2リリース
なんだかんだ言って、月1でリリースする。
Sagittarius Scheme 0.3.2をリリースしました。今回のリリースはメンテナンスリリースです。
修正された不具合
Sagittarius Scheme 0.3.2をリリースしました。今回のリリースはメンテナンスリリースです。
修正された不具合
- call-next-methodがsyntax-caseマクロ内で呼び出せない不具合が修正されました。
- 特定のプロシージャ呼び出しが失敗する不具合が修正されました。
- transcoded-portを使ってカスタムバイナリポートを変換するとput-string等のプロシージャでSEGVを起こす問題が修正されました。
- R6RSで定義されていて、実装されていなかったマクロassertが追加されました。
- portクラスの階層が修正されました。
- ソケットポートを使用してget-bytevector-allを呼び出すと終了しない場合がある不具合が修正されました。
- X.509証明書を読み込む際にmake-basic-constraintsがエラーを投げる不具合が修正されました。
- open-inflating-input-portのreadプロシージャで読み込み数が1より大きい場合に例外を投げる不具合が修正されました。これは今回のカスタムポート改善で発覚したもので、0.3.1以前では発現しません。
- X.509証明書をキーストアから読み込む際、秘密鍵のみを読み込んで証明書自体を読み込まない不具合が修正されました。
- bytevector、stringアウトプットポートから出力されたデータを読み出した際に、ポート位置がリセットされていない不具合が修正されました。
- カスタムバイナリアウトプットポートの出力の際に、ある程度のサイズのバッファを渡すように修正されました。パフォーマンスが改善されているはずです。
- bytevector-copyがオプション引数startとendをとるように改善されました。
- base64-decode-stringがオプショナル引数のtranscoderで#fを受け取った際に生のバイトベクタを返すように改善されました。
- バイトベクタ及びストリングのアウトプットポートのパフォーマンスが改善されました。およそ2倍程度高速になっているはずです。
- 擬似乱数クラスがハッシュやCipherと同様拡張可能になりました。
- キャッシュ機構がScheme側からも制御できるようになりました。
- 上記の改善により、正規表現パターンのリーダがS式ではなくパターンオブジェクトを返すようになりました。
- 擬似乱数クラスの変更により、custom-prng?プロシージャが削除されました。
- OAuthライブラリ(net oauth)が追加されました。OAuth 1.0のコンシューマをサポートしています。
- TLSプロトコルライブラリ(rfc tls)が追加されました。TLS1.0からTLS1.2までをサポートしていますが、1.2に関しては動作保障がありません。セキュリティホール等があるかもしれません。
- (srfi :27 random-bits)が追加されました。
- バリデーションメタクラスライブラリ(sagittaius mop validator)が追加されました。
2012-05-14
継続してリリースをするということ
ふと、moshにバグレポートをして思ったこと。軽くdisるので先に謝っておこう、ごめんなさい。
前提として、開発版は使わないとします。 なので、trunkからとってくれば直っているよっていうのは議論からは外します。
Sagittariusは意図していなかったのだが月1ペースでリリースをするという習慣になっている。いい悪いはとりあえず置いておくとしてだが。
っで、moshなのだが、最新版は0.2.7でリリースされたのが2011年6月7日とほぼ一年前。その前のバージョン0.2.6も2010年11月7日と半年以上の期間が空いている。もちろん製作者側がすでに「moshは十分に枯れていて、今後新しい機能を足すことも少なく、バグもほぼない」と判断しているならば問題ないのかもしれないのだが、メインで使っていない僕が3つほどバグレポートをし、そのうちの1つはクリティカル(mosh自体が止まる)ものだったりする。大多数はバグレポートにある使い方をしないだろうので、問題ないといえばそうなのだが、レポートにある使い方をする必要がある少数派の人間はいつ直ってリリースされるか分からない処理系を使う気にはならないだろう。
一方で僕は月1でリリースしている。正直必要性をあまり感じない上に、ユーザーもいない(更には自分以外のバグレポートはない)のだが、レポートした人はそれなりに速いうちにそのバグが直されてリリースされるだろうということが予測できる。もちろん弊害もあって、そんな頻繁に更新される処理系怖くて使えないという話にもなる。
もちろん、僕がリリースするということを甘く見ているだけなのかもしれない。WindowsとLinuxでテスト通して、ドキュメント整備してくらいにしか考えてない部分はある。moshと違ってFreeBSDのポート作ってとかないので。
月1でリリースするならそろそろ準備しないとなぁ・・・
前提として、開発版は使わないとします。 なので、trunkからとってくれば直っているよっていうのは議論からは外します。
Sagittariusは意図していなかったのだが月1ペースでリリースをするという習慣になっている。いい悪いはとりあえず置いておくとしてだが。
っで、moshなのだが、最新版は0.2.7でリリースされたのが2011年6月7日とほぼ一年前。その前のバージョン0.2.6も2010年11月7日と半年以上の期間が空いている。もちろん製作者側がすでに「moshは十分に枯れていて、今後新しい機能を足すことも少なく、バグもほぼない」と判断しているならば問題ないのかもしれないのだが、メインで使っていない僕が3つほどバグレポートをし、そのうちの1つはクリティカル(mosh自体が止まる)ものだったりする。大多数はバグレポートにある使い方をしないだろうので、問題ないといえばそうなのだが、レポートにある使い方をする必要がある少数派の人間はいつ直ってリリースされるか分からない処理系を使う気にはならないだろう。
一方で僕は月1でリリースしている。正直必要性をあまり感じない上に、ユーザーもいない(更には自分以外のバグレポートはない)のだが、レポートした人はそれなりに速いうちにそのバグが直されてリリースされるだろうということが予測できる。もちろん弊害もあって、そんな頻繁に更新される処理系怖くて使えないという話にもなる。
もちろん、僕がリリースするということを甘く見ているだけなのかもしれない。WindowsとLinuxでテスト通して、ドキュメント整備してくらいにしか考えてない部分はある。moshと違ってFreeBSDのポート作ってとかないので。
月1でリリースするならそろそろ準備しないとなぁ・・・
2012-05-12
TLSを実装したった
ようやく動くものが出来た。まだまだ、作りこみが甘いので予期せぬ挙動が起きると直ぐエラーを投げるが、ある意味セキュアであろう。また、セッションの復元も行えない。
現状ではTLS 1.0と1.1に対応している。1.2もサポートをしたいのだが、動作を検証できる環境が簡単に構築できそうにないので、厳しいところではある。多くのサーバーは1.0もしくはで動作しているはずなので大きな問題になるとは思わないが、ハンドシェイクで0x0303を投げるので、1.2対応のサーバーが多くなると問題が起きそうではある。
また、現状ではクライアントソケットのみの対応である。サーバーソケットが必要な状況が当面僕にはないので、しばらくは対応する予定はない。
なぜわざわざ自前で実装したのか?
世の中にはOpenSSLとか優れた実装がたくさんあるのだから、それをおとなしく使えばいいではないか?実際そうしようかなぁと思ったのだけど、ビルド時の依存関係を極力減らしたいのと、暗号ライブラリが自前であるのにさらに他の実装に依存するのがイヤだったというだけ。ビルド時の依存関係は、現状Windowsでのビルドを極力簡便にするため。現状ではWindowsでのビルドはネットに繋がってさえ要れば何も用意することなくビルドが進むようになっている(もちろんCMakeとVCは要るけど)。この方針を崩したくなかった。
また、Cの実装はたくさんあるけど、Pure Scheme(Lispを含めても)な実装ってないのであってもいいかなぁと。
セキュアなの?
実装上のセキュリティーホールはまだまだあるだろうとは思う。サーバーの証明書を検証してないし。また、実装してて思ったことだが、TLSは暗号セッションが始まってしまえば現状安心して使えるプロトコルだと思うが、ハンドシェイクの段階から盗聴されていた場合はその限りではないと思う。理由はこの辺。
急いで作った理由はOAuth使ってTwitterに呟いているときに、TwitterのAPIにはhttpsがあることに気づいたから。折角だし、セキュアなOAuthにしてしまいたかった。思いの他時間がかかったが、動くのそれまでの苦労が吹き飛ぶ。
現状ではTLS 1.0と1.1に対応している。1.2もサポートをしたいのだが、動作を検証できる環境が簡単に構築できそうにないので、厳しいところではある。多くのサーバーは1.0もしくはで動作しているはずなので大きな問題になるとは思わないが、ハンドシェイクで0x0303を投げるので、1.2対応のサーバーが多くなると問題が起きそうではある。
また、現状ではクライアントソケットのみの対応である。サーバーソケットが必要な状況が当面僕にはないので、しばらくは対応する予定はない。
なぜわざわざ自前で実装したのか?
世の中にはOpenSSLとか優れた実装がたくさんあるのだから、それをおとなしく使えばいいではないか?実際そうしようかなぁと思ったのだけど、ビルド時の依存関係を極力減らしたいのと、暗号ライブラリが自前であるのにさらに他の実装に依存するのがイヤだったというだけ。ビルド時の依存関係は、現状Windowsでのビルドを極力簡便にするため。現状ではWindowsでのビルドはネットに繋がってさえ要れば何も用意することなくビルドが進むようになっている(もちろんCMakeとVCは要るけど)。この方針を崩したくなかった。
また、Cの実装はたくさんあるけど、Pure Scheme(Lispを含めても)な実装ってないのであってもいいかなぁと。
セキュアなの?
実装上のセキュリティーホールはまだまだあるだろうとは思う。サーバーの証明書を検証してないし。また、実装してて思ったことだが、TLSは暗号セッションが始まってしまえば現状安心して使えるプロトコルだと思うが、ハンドシェイクの段階から盗聴されていた場合はその限りではないと思う。理由はこの辺。
急いで作った理由はOAuth使ってTwitterに呟いているときに、TwitterのAPIにはhttpsがあることに気づいたから。折角だし、セキュアなOAuthにしてしまいたかった。思いの他時間がかかったが、動くのそれまでの苦労が吹き飛ぶ。
2012-05-11
quicklispのインストールからcl-annotまで
Lisperになるつもりはあまりないのだが、試してみたいライブラリが結構あるのでquicklispをインストールしてみる。対象はclisp on Cygwin。
とりあえずquicklisp 。
手順に従ってquicklispをインストールしようとしたら、早速curlがないと怒られた・・・しょうがないのでインストール。
Installationにしたがって以下の用にquicklisp.lispのダウンロードと、clispの起動。上記サイトはsbclなので多少コマンドラインのオプションが違う。
とりあえずquicklisp 。
手順に従ってquicklispをインストールしようとしたら、早速curlがないと怒られた・・・しょうがないのでインストール。
Installationにしたがって以下の用にquicklisp.lispのダウンロードと、clispの起動。上記サイトはsbclなので多少コマンドラインのオプションが違う。
$ curl -O http://beta.quicklisp.org/quicklisp.lisp
$ clisp -i quicklisp.lisp
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ `+' / I 8 8 8 8 8 8
\ `-+-' / 8 8 8 ooooo 8oooo
`-__|__-' 8 8 8 8 8
| 8 o 8 8 o 8 8
------+------ ooooo 8oooooo ooo8ooo ooooo 8
Welcome to GNU CLISP 2.48 (2009-07-28) <http://clisp.cons.org/>
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2009
Type :h and hit Enter for context help.
;; Loading file quicklisp.lisp ...
==== quicklisp quickstart loaded ====
To continue with installation, evaluate: (quicklisp-quickstart:install)
For installation options, evaluate: (quicklisp-quickstart:help)
;; Loaded file quicklisp.lisp
っで、clispのREPL上でプロンプトに表示されている注意書きにしたがってインストールを続行。
[1]> (quicklisp-quickstart:install)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/asdf.lisp">
; 159.59KB
==================================================
163,424 bytes in 0.89 seconds (180.28KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/quicklisp.tar">
; 210.00KB
==================================================
215,040 bytes in 0.16 seconds (1280.11KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/setup.lisp">
; 4.88KB
==================================================
4,995 bytes in 0.00 seconds (1625.43KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp.txt">
; 0.40KB
==================================================
408 bytes in 0.01 seconds (56.90KB/sec)
==== quicklisp installed ====
To load a system, use: (ql:quickload "system-name")
To find systems, use: (ql:system-apropos "term")
To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)
For more information, see http://www.quicklisp.org/beta/
NIL
何か読み込まれた。本当はql:aproposとかで何があるか調べるんだろうけど、cl-annotがあることはすでに知っているのでそのままインストール。
[2]> (ql:quickload "cl-annot")
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2012-04-07/systems.txt">
; 123.72KB
==================================================
126,685 bytes in 0.10 seconds (1236.79KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2012-04-07/releases.txt">
; 175.60KB
==================================================
179,810 bytes in 0.15 seconds (1170.87KB/sec)
To load "cl-annot":
Install 2 Quicklisp releases:
alexandria cl-annot
; Fetching
#<URL
"http://beta.quicklisp.org/archive/alexandria/2012-04-07/alexandria-20120407-git.tgz">
; 47.16KB
==================================================
48,296 bytes in 0.04 seconds (1274.98KB/sec)
; Fetching
#<URL
"http://beta.quicklisp.org/archive/cl-annot/2011-12-03/cl-annot-20111203-git.tgz">
; 8.16KB
==================================================
8,356 bytes in 0.00 seconds (2720.05KB/sec)
; Loading "cl-annot"
[package alexandria.0.dev]........................
[package cl-annot.util]...........................
[package cl-annot.core]...........................
[package cl-annot.expand].........................
[package cl-annot.syntax].........................
[package cl-annot.helper].........................
[package cl-annot]................................
[package cl-annot.std]............................
[package cl-annot.eval-when]......................
[package cl-annot.doc]............................
[package cl-annot.class]..........................
[package cl-annot.slot]
("cl-annot")
パースに時間がかかるのか、落としてくるまでに結構時間がかかった。が、うまいこといっている感じがする。REPL上のコマンドは基本的にはどの処理系でも動くはずなので、後は省略。っで、cl-annot
[4]> (asdf:load-system :cl-annot) 0 errors, 0 warnings T [5]> (use-package :cl-annot) T [6]> (enable-annot-syntax) T [7]> @print 1 1 1動いた。
2012-05-09
知る権利、個人情報保護
一つ前の投稿の続きである。武雄市図書館問題のごく1部、具体的には知る権利及び個人情報保護を扱ったものでもある。
注意書き。
参照資料
https://twitter.com/#!/hiwa1118/status/200220121770373120
次に個人情報保護法についてです。この問題の焦点は武雄市市長のブログで言及されていた、
Twitter上でこの問題についてのハッシュタグを見た際に、知る権利の侵害及び個人情報保護法違反だという批判を見かけ、法律上だけ見ればそのようなことはないという旨の意見を比較的曖昧な表現を用いて書いたところ、複数の方から突込みが入ったので具体的に記載した。また、私はこの問題自体についてはいくつか批判または議論すべき点が多々あると思っているが、ここでは言及しない。
なおこの問題において、武雄市市長は個人情報保護法には抵触していないという旨を上記のブログで言及しているが、プライバシー保護については言及されていない。 Twitter上では現在個人情報保護ではなくプライバシー保護の観点から問題について言及しているようである。
以下、チラシの裏
注意書き。
- 私は法律の専門家ではないので、下記の文章には誤りが含まれている可能性があります。
- 断りがない限り下記の文章は武雄市図書館問題に置けるTwitter上の議論に対しての意見です。
- 断定する形で書いていますが、すべて下記の資料に基づく私の個人的意見です。法律的正しさを証明するものではありません。
参照資料
- 表現の自由 (日本国憲法第21条第1項)
- 個人情報の保護に関する法律
- 図書館法
- 図書館の自由に関する宣言
- 個人情報保護とプライバシー保護の違い(朝日中央インターネット法律相談)
https://twitter.com/#!/hiwa1118/status/200220121770373120
図書館の本は図書館法により無償です。 RTまた、図書館法にも貸出に関しての記述は一切ありません。利用者は無料でいかなる図書をも閲覧可能であるため、知る権利の侵害にはなりません。ただし、Tカードなしでの図書館の利用については言及されていないので、図書館利用者はTカードに登録する必要があるということがあればこの限りではありません。@mikozakuran@hiwa1118 お疲れ様です。時々ツイート拝見させていただいています。武雄市図書館について質問です。業務委託後、図書館の本にレンタル料を課す可能性はありますか?#takeolibrary
次に個人情報保護法についてです。この問題の焦点は武雄市市長のブログで言及されていた、
「5月6日20時40分、42歳の市内在住の男性が、「深夜特急」「下町ロケット」「善の研究」」
From 図書館貸出情報の扱い、ご安心ください!という情報が個人情報保護法で保護されるべき個人情報に当たるかどうか、という点である。個人情報の保護に関する法律第二条によれば、
この法律において「個人情報」とは、生存する個人に関する情報であって、当該情報に含まれる氏名、生年月日その他の記述等により特定の個人を識別すること ができるもの(他の情報と容易に照合することができ、それにより特定の個人を識別することができることとなるものを含む。)をいう。と定義されている。定義のみを見れば明確ではなく、読み手の裁量によって大きく範囲が動くものだ。ここでは、不特定多数の第三者によって容易に特定できる情報とする。その仮定に基づけば上記の情報には氏名、生年月日及び特定の個人を識別する情報は含まれていない。 となれば、上記の情報は個人情報保護法ではなくプライバシー保護に分類されるものである。(過去の判例があればその限りではない)。個人情報保護とプライバシー保護の違いについては参照情報の5を参照されたい。また、図書館の自由に関する宣言はあくまで宣言なので法的束縛はない。事実、第3条の1には裁判所の令状があれば情報を開示するとある。ただし、私が寡聞ゆえに誤認している可能性はある。
Twitter上でこの問題についてのハッシュタグを見た際に、知る権利の侵害及び個人情報保護法違反だという批判を見かけ、法律上だけ見ればそのようなことはないという旨の意見を比較的曖昧な表現を用いて書いたところ、複数の方から突込みが入ったので具体的に記載した。また、私はこの問題自体についてはいくつか批判または議論すべき点が多々あると思っているが、ここでは言及しない。
なおこの問題において、武雄市市長は個人情報保護法には抵触していないという旨を上記のブログで言及しているが、プライバシー保護については言及されていない。 Twitter上では現在個人情報保護ではなくプライバシー保護の観点から問題について言及しているようである。
以下、チラシの裏
図書館利用しないからあんまり関係ないけど
こんなツイートを見つけた。
https://twitter.com/#!/fmht7/status/200074782732075008
っで、何のことだろう?と思い、元ネタを探してみた。多分これ?
図書館貸出情報の扱い、ご安心ください!
あまり詳しく知らないのでなんともいえないが、貸し出し履歴って個人情報か?というか、管理される情報って
そもそも、日本の図書館は大分優遇されていると思うのだが、どうだろう?カナダもそうだが、オランダの図書館は有料である。カード作ったことないので分からないけど、多分図書カードも有料じゃないかな?閲覧自体は無料。
正直Twitterの議論って的外れな感じではあるのだが、「知る権利」の保障と貸し出し履歴は関係ないだろう。また、図書の閲覧自体はTカードがなくてもできる(と仮定する)なら、保障されてるよね?自宅に持ち帰るということは、「その本が返却される、またはされなかった際になんらかの行動が取れる」状態にしておかないと、「他の人の知る権利の侵害」ならないかね?(もちろん、Tカード作らなきゃ閲覧も不可っていうなら話は違ってくるが)
ツイートを全部読んだわけじゃないし、何を問題視してるのかも漠然としてるんだけど、これが炎上することがいまいち不思議。
(時間がない、面倒くさいというのもあり)詳しく知らないので、賛否の意見は控えるけど(ずるいのは承知の上)、問題視する点が違わないかな?
https://twitter.com/#!/kuippa/status/200088650367774720
まじめに意見を書いた。
https://twitter.com/#!/fmht7/status/200074782732075008
CCCとの提携の件白紙に戻し再検討が良いとお考えの方はRTを。(bloggerでTwitterの参照ってどうやるんだ?)#takeolibrary RT@ryoumax:@fmht7@hiwa1118@kokusanlaw 沢山いらっしゃる?何人ぐらい?そんな何の根拠もない言い方するから反対にしても上っ面にしかならないんだよ
っで、何のことだろう?と思い、元ネタを探してみた。多分これ?
図書館貸出情報の扱い、ご安心ください!
あまり詳しく知らないのでなんともいえないが、貸し出し履歴って個人情報か?というか、管理される情報って
「5月6日20時40分、42歳の市内在住の男性が、「深夜特急」「下町ロケット」「善の研究」」このレベルらしいのだが?(真偽の程は定かではないが)。噂では炎上しているらしい?もちろん、提携先のCCCという会社のセキュリティがどれほどかとか、その会社は取得した個人情報(上記の情報?)を悪用しない、または管理目的以外には使用しないということが保障されるのかというのは別の話だが。
そもそも、日本の図書館は大分優遇されていると思うのだが、どうだろう?カナダもそうだが、オランダの図書館は有料である。カード作ったことないので分からないけど、多分図書カードも有料じゃないかな?閲覧自体は無料。
正直Twitterの議論って的外れな感じではあるのだが、「知る権利」の保障と貸し出し履歴は関係ないだろう。また、図書の閲覧自体はTカードがなくてもできる(と仮定する)なら、保障されてるよね?自宅に持ち帰るということは、「その本が返却される、またはされなかった際になんらかの行動が取れる」状態にしておかないと、「他の人の知る権利の侵害」ならないかね?(もちろん、Tカード作らなきゃ閲覧も不可っていうなら話は違ってくるが)
ツイートを全部読んだわけじゃないし、何を問題視してるのかも漠然としてるんだけど、これが炎上することがいまいち不思議。
(時間がない、面倒くさいというのもあり)詳しく知らないので、賛否の意見は控えるけど(ずるいのは承知の上)、問題視する点が違わないかな?
https://twitter.com/#!/kuippa/status/200088650367774720
これをうまく収めることができるなら図書館だけじゃなくて炎上対策のモデルケースにもなるね・・・! (キリッこれには激しく同意した。#takeolibrary
まじめに意見を書いた。
2012-05-08
セキュリティについての考察
SSL/TLSのおけるセキュリティの考察。
実装がまったく行き詰っていて、息抜きにふと思いついたことをつらつら書いているとも言う。
以下に記載した内容に基づいて盗聴、改竄を行ったとしても当方は一切責任を取らない。また、この記事はそのような犯罪行為を推奨するものでもない。(お約束の免責事項)
ふと、ひょっとしたらハッキング(世間一般的に通じる言い方、本当はクラッキングと言う。一応)できるんじゃね?と思ったのでその手順。もちろん試してないし、僕にそのようなことが出来る技術はない。ただ仕様書を読んでいて出来そうだと思っただけ。
【用意するもの】
もちろん、この程度のことはきっと議論され尽くしているはずなので基本的には問題にならないと思う。っが、RFCだけ見た感じだとそんなこと考えられてなかったので、どうなんだろう?
実装がまったく行き詰っていて、息抜きにふと思いついたことをつらつら書いているとも言う。
以下に記載した内容に基づいて盗聴、改竄を行ったとしても当方は一切責任を取らない。また、この記事はそのような犯罪行為を推奨するものでもない。(お約束の免責事項)
ふと、ひょっとしたらハッキング(世間一般的に通じる言い方、本当はクラッキングと言う。一応)できるんじゃね?と思ったのでその手順。もちろん試してないし、僕にそのようなことが出来る技術はない。ただ仕様書を読んでいて出来そうだと思っただけ。
【用意するもの】
- 偽のサーバー証明書
- なりすまし用のルータ
- SSL/TLSのパケットを作れる技術
- クライアントが送ってきたCLIENT-HELLOのcipher suitesからDHなsuitesを取り除いてサーバーに送る。このときクライアントの乱数を記録しておく。
- サーバーが送ってくる情報のうち、決定したcipher suite、サーバーの乱数、サーバー証明書を抜き取る。また、サーバー証明を用意した偽の証明書と置き換えてクライアントに送る。
- クライアントがpre master secretを暗号化したものを送ってくるので、偽の証明書の秘密鍵で複合。master secretを作成する。また、送られてきたpre master secretを本物の証明書で暗号化してサーバーに送る。
- 以下、暗号化されたメッセージは手元のマスター鍵で複合したり、MACを合成したりしてなりすます。
- Deffie-Hellmanを使われると現在のところ現実的な時間で鍵を手に入れることができないので、クライアントがサポートしているcipherから抜き取る必要がある。
- この時点でサーバーの証明書を抜き取ってしまえば、クライアントは成りすまし証明書を検出する方法はない。
- クライアントに対してはサーバーの振り、クライアントに対してはサーバーの振りをする。しないと不整合が起きるので。
もちろん、この程度のことはきっと議論され尽くしているはずなので基本的には問題にならないと思う。っが、RFCだけ見た感じだとそんなこと考えられてなかったので、どうなんだろう?
2012-05-06
プロトコルの実装とナンパ
なんとなく2つは似ている気がする。TLSの実装をしていてふとそう思った。
ナンパはしたことがないのでネットで読んだ知識になるのだが、以下の流れだろう。
並べてみただけだが、既にほとんど一緒だなぁ。どちらも成功するか失敗するかは声のかけ方、交渉の仕方による。(まぁ、ナンパはさらに顔面偏差値などもいるだろうが、これは声のかけ方に含める)
ただ一点絶対的に違うのは、手順さえきっちりしてればプロトコルの実装は失敗しないという点。サーバーに選択権はないけど、異性にはあるということだ。そういう意味ではサーバーを落とす方がはるかに簡単といえるだろう。
何書いてんるんだろう、俺・・・orz
ナンパはしたことがないのでネットで読んだ知識になるのだが、以下の流れだろう。
- 異性に声をかける
- 交渉する
- 目的を達する
- バイバイする
- ハローってサーバーに言う
- 交渉する
- データ交換する
- バイバイする
並べてみただけだが、既にほとんど一緒だなぁ。どちらも成功するか失敗するかは声のかけ方、交渉の仕方による。(まぁ、ナンパはさらに顔面偏差値などもいるだろうが、これは声のかけ方に含める)
ただ一点絶対的に違うのは、手順さえきっちりしてればプロトコルの実装は失敗しないという点。サーバーに選択権はないけど、異性にはあるということだ。そういう意味ではサーバーを落とす方がはるかに簡単といえるだろう。
何書いてんるんだろう、俺・・・orz
2012-05-05
プログラマはキチガイじゃないよ
こんなのを見つけた。
プログラム板キチガイすぎワロタwwwwww
ム板とマ板は違うとあれほど(ryというのはほっといて。
内容は2004年に立てられた何かのスレに対してのコメント。そのスレの>>1が2進数で何か書いていて何言ってるんだろう?という話。
2進数なら単に2->16->変換でいけるだろうとこんなの書いてみた。文字コードの判別は面倒だったのでSJIS決め打ち。(2004年だとUTF-8はそんなに普及してなかったなぁ・・・遠い目)
元スレの>>1がEBCDICでも使っているのか、でたらめだったのかは知らないけど。朝の15分であんまり頑張りたくないのでやめた。
元ネタがなんて書いてあるか知りたい人は是非Sagittariusをダウンロードして
プログラム板キチガイすぎワロタwwwwww
ム板とマ板は違うとあれほど(ryというのはほっといて。
内容は2004年に立てられた何かのスレに対してのコメント。そのスレの>>1が2進数で何か書いていて何言ってるんだろう?という話。
2進数なら単に2->16->変換でいけるだろうとこんなの書いてみた。文字コードの判別は面倒だったのでSJIS決め打ち。(2004年だとUTF-8はそんなに普及してなかったなぁ・・・遠い目)
#< (sagittarius regex) >
(import (rnrs) (getopt)
(sagittarius)
(sagittarius control)
(sagittarius regex)
(encoding sjis)
(util file))
(define (sjis->string bv)
(let1 tr (make-transcoder (sjis-codec))
(bytevector->string bv tr)))
(define (main args)
(with-args args
((i (#\i "input") #t (usage)))
(let1 s (regex-replace-all #/\s/ (car (file->string i)) "")
(print (sjis->string (integer->bytevector (string->number s 2)))))))
Sagittariusはこっそり拡張コーデックを持っているので、sjisとeuc-jpが使える。今回はsjisだけど。っで、満を持して元スレの>>1を解読したら、>>2になった。元スレの>>1がEBCDICでも使っているのか、でたらめだったのかは知らないけど。朝の15分であんまり頑張りたくないのでやめた。
元ネタがなんて書いてあるか知りたい人は是非Sagittariusをダウンロードして
$ sash {スクリプト名} -i {2進数を貼り付けたファイル名}
コマンドラインから上記スクリプトでw
2012-05-03
SSL/TLSを実装したいの1
2があるかは知らない・・・ついでに、OpenSSL使えよという囁きが頭の中で木霊しているけど無視。
TLS1.1と1.2をSchemeで実装してhttpsとか使えるようにしたい、という願望の元とりあえず資料集めをしてみた。
基本はRFCを読めば全部書いてあるんだけど、分量が多いのと送信データが分かり辛い。2つ目のリンクは最初のネゴシエーションで使うデータが詳しく書いてあって参考になる。解説自体はSSL3.0のものだが、TLSでも基本的な部分は変わらない。違いはRFCを見て吸収。
CLIENT-HELLOを送ってSERVER-HELLOを受け取る事まではできた(データ送ればサーバが送り返してくるから当たり前だが)。っで、気づいたこと。
TLS1.1と1.2をSchemeで実装してhttpsとか使えるようにしたい、という願望の元とりあえず資料集めをしてみた。
基本はRFCを読めば全部書いてあるんだけど、分量が多いのと送信データが分かり辛い。2つ目のリンクは最初のネゴシエーションで使うデータが詳しく書いてあって参考になる。解説自体はSSL3.0のものだが、TLSでも基本的な部分は変わらない。違いはRFCを見て吸収。
CLIENT-HELLOを送ってSERVER-HELLOを受け取る事まではできた(データ送ればサーバが送り返してくるから当たり前だが)。っで、気づいたこと。
- 生のバイトベクターをゴリゴリやるより、クラス作って抽象化した方が楽。
- ASN.1(というかDER)と同じ方式。
- パフォーマンスとコード量が気になるが、まぁいいか。
- サーバーから返ってくるデータをどう処理しよう。
- TLS1.2(SSL version 3.3)としてハローって言ったのに、TLS1.1でハローって返される。
- 違いってCipherSuiteだけ?
2012-05-02
Wicketが腐っているなぁと思った瞬間
Apache Wicketのことです。
事の発端はCheckGroupにAjaxFormComponentUpdatingBehaviorが渡せないということに昨日から1日悩んでいた話。サンプルはまったく見つからないし、Javadocにも特にその辺の説明はない。Google先生で検索をかけてもキーワードが悪かったので見つからない(今は解決した)。
っで、今日ちょっと頭を冷やして検索してみたらこんなスレッドを発見。
DropDownChoice, AjaxFormComponentUpdatingBehavior and dijit.form.FilteringSelect
最初に検索したときは使っているのがCheckGroupなので無視したのだが、藁にもすがる思いで覗いてみた。書いてある指摘としては、AjaxFormChoiceComponentUpdatingBehaviorを使えというもの。しかも、それがさも当たり前のように、「驚いた、実に驚いた、またこのスレだ・・・」みたいな回答がついてる。(まぁ、確かに過去ログ見ろというのも分かるが)
でも、一日3つも同様の質問が出るくらい頻繁に使われるものなのに、ドキュメントはないわ、サンプルはないわじゃ、あまり嫌味を言える立場ではないと思うのだが。 しかも、何このクラス名。混乱を招くに決まっている。せめて「このBehaviorは無視されます」、みたいなログ出してもいいだろうに、それもない。あほか!
単に、昨日一日無駄にしたので愚痴りたくなっただけ。どこかにあったなぁ、私がモダンフレームワークを嫌う理由みたいなネタ。そこからじゃないけど、「それってドキュメントあるんだよね?」って気分。
事の発端はCheckGroupにAjaxFormComponentUpdatingBehaviorが渡せないということに昨日から1日悩んでいた話。サンプルはまったく見つからないし、Javadocにも特にその辺の説明はない。Google先生で検索をかけてもキーワードが悪かったので見つからない(今は解決した)。
っで、今日ちょっと頭を冷やして検索してみたらこんなスレッドを発見。
DropDownChoice, AjaxFormComponentUpdatingBehavior and dijit.form.FilteringSelect
最初に検索したときは使っているのがCheckGroupなので無視したのだが、藁にもすがる思いで覗いてみた。書いてある指摘としては、AjaxFormChoiceComponentUpdatingBehaviorを使えというもの。しかも、それがさも当たり前のように、「驚いた、実に驚いた、またこのスレだ・・・」みたいな回答がついてる。(まぁ、確かに過去ログ見ろというのも分かるが)
でも、一日3つも同様の質問が出るくらい頻繁に使われるものなのに、ドキュメントはないわ、サンプルはないわじゃ、あまり嫌味を言える立場ではないと思うのだが。 しかも、何このクラス名。混乱を招くに決まっている。せめて「このBehaviorは無視されます」、みたいなログ出してもいいだろうに、それもない。あほか!
単に、昨日一日無駄にしたので愚痴りたくなっただけ。どこかにあったなぁ、私がモダンフレームワークを嫌う理由みたいなネタ。そこからじゃないけど、「それってドキュメントあるんだよね?」って気分。
2012-04-29
The reason to be here
Since I don't have any reason, I have been thinking why I'm still here and where I want to go. I haven't found any answer of it. One thing I know for sure is, I don't want to be here so long and even I'm not sure whether I can or not because of the visa.
The problem is, however, I got too much use to be in non harsh working environment. Yes, European working style is excellent if I compare with Japanese one. So I'm also seriously looking for a job in Japan or somewhere in the world. Well if it's not in the Netherlands, it would be fine by me... maybe not... in UK maybe, at least no language barrier.
Things are not so going easy. But I must get out from this suffocating atmosphere. What can I do for it? Think.
The problem is, however, I got too much use to be in non harsh working environment. Yes, European working style is excellent if I compare with Japanese one. So I'm also seriously looking for a job in Japan or somewhere in the world. Well if it's not in the Netherlands, it would be fine by me... maybe not... in UK maybe, at least no language barrier.
Things are not so going easy. But I must get out from this suffocating atmosphere. What can I do for it? Think.
2012-04-26
Twitterに投稿できた!
(net oauth)というライブラリを作成中。cl-oauthの移植なんだけど、drakmaとかのライブラリはあるわけ無いのでAPI名と処理の流れだけ。
Service Providerまで作る必要はないよなぁと思っているのでConsumerだけ。気が向いたらそのうち実装するかも。
っで、とりあえずTwitterに投稿できたので浮かれて書いてる。コードは以下。
これで仕事してる振りして呟ける(違
そういえば、OAuthの2.0どうしよう。今の作りだとガッツリ1.0用だ・・・
Service Providerまで作る必要はないよなぁと思っているのでConsumerだけ。気が向いたらそのうち実装するかも。
っで、とりあえずTwitterに投稿できたので浮かれて書いてる。コードは以下。
(import (rnrs) (net oauth) (text sxml ssax)
(sagittarius io)
(srfi :26 cut))
(define (call/twitter-api->sxml token method path param . opt)
(define (call)
(if token
(access-protected-resource (string-append "http://api.twitter.com" path)
token
:user-parameters param
:request-method method)
(assertion-violation 'call/twitter-api->sxml
"later")))
(define (retrieve body status hint advice)
(call-with-input-string body (cut ssax:xml->sxml <> '())))
(call-with-values call retrieve))
(define (twitter-update/sxml token message . opt)
(call/twitter-api->sxml token 'POST "/1/statuses/update.xml"
`(("status" ,message))))
(define access-token (make-access-token
:key "アクセストークンを入れてね"
:secret "アクセスシークレットを入れてね"
:consumer
(make-consumer-token
:key "コンシューマトークンを入れてね"
:secret "コンシューマシークレットを入れてね")))
(print
(twitter-update/sxml access-token "Hello world from Sagittarius Scheme!!"))
これだけで投稿が出来た。まぁ、アクセストークンを作る部分とかもあるんだけど、一度作ったら使いまわしなので略。Twitter用のAPI集はSagittarius本体に入れるつもりはないんだけど、どこかに置けたらいいなぁ。これで仕事してる振りして呟ける(違
そういえば、OAuthの2.0どうしよう。今の作りだとガッツリ1.0用だ・・・
2012-04-23
OAuthを調べる。
その昔(3ヶ月くらい前?)にSagittariusからTwitterに投稿してみようとして挫折したことがあった。理由はHMACがないから。っで、今はあるので、仕様を理解すればいけるのかなぁと思いちょっと調べてみた。
とりあえず現行のバージョンは1.0なんだけど、2.0も策定中でFacebook、mixi及びその他(忘れた)が先行採用しているらしい。2.0の方はSSLが必須になるので、サポートするのはちと厳しい。(TLSが実装できたらやることにするとして、中身を簡単に入れ替えられるように実装する必要はあるか・・・)
詳しい中身はRFC5849を見ることにして、概要をとりあえず頭に入れたい。っで下記のページが分かりやすかった。
APIアクセス権を委譲するプロトコル、OAuthを知る - @IT
署名とかの処理を除けば処理フローは割りと簡単な感じ。サーバー側を書くつもりは今のところないので、必要な登場人物としては、Consumer(RFCではClientになっている)だけだろう。流れとしては、
しかし、OAuthと書いてオースとは読めない自分。どうしてもオーオースになる。
とりあえず現行のバージョンは1.0なんだけど、2.0も策定中でFacebook、mixi及びその他(忘れた)が先行採用しているらしい。2.0の方はSSLが必須になるので、サポートするのはちと厳しい。(TLSが実装できたらやることにするとして、中身を簡単に入れ替えられるように実装する必要はあるか・・・)
詳しい中身はRFC5849を見ることにして、概要をとりあえず頭に入れたい。っで下記のページが分かりやすかった。
APIアクセス権を委譲するプロトコル、OAuthを知る - @IT
署名とかの処理を除けば処理フローは割りと簡単な感じ。サーバー側を書くつもりは今のところないので、必要な登場人物としては、Consumer(RFCではClientになっている)だけだろう。流れとしては、
- リクエストトークンの取得
- ユーザー認証
- アクセストークンの発行
- APIを叩く
しかし、OAuthと書いてオースとは読めない自分。どうしてもオーオースになる。
2012-04-20
簡易PEMファイルリーダー
とりあえずささっと作ってみた。X509証明書のみに対応という手抜きっぷり。
#!/usr/local/bin/sash
#< (sagittarius regex) >
(import (rnrs) (asn.1) (getopt)
(sagittarius)
(sagittarius regex)
(sagittarius control)
(rfc base64)
(rfc x.509)
(util file))
(define (read-content p end)
(let loop ((line (get-line p))
(r ""))
(if (eof-object? line)
(assertion-violation 'read-content "unexpected eof")
(cond ((looking-at #/-----END (\w+)-----/i line)
=> (lambda (m)
(unless (string=? (m 1) end)
(assertion-violation 'read-content
"invalid pem file"))
r))
(else
(loop (get-line p)
(string-append r line)))))))
(define (parse-pem-file in)
(call-with-input-file in
(lambda (p)
(let loop ((line (get-line p)))
(unless (eof-object? line)
(cond ((looking-at #/-----BEGIN (\w+)-----/i line)
=> (lambda (m)
;; read until end comes
(let1 base64 (base64-decode-string (read-content p (m 1))
#f)
(print (make-x509-certificate
(open-bytevector-input-port base64))))))
(else
(loop (get-line p)))))))))
(define (usage args)
(format (current-error-port) "usage: ~a -i file~%" (car args))
(exit -1))
(define (main args)
(with-args args
((in (#\i "input") #t (usage args)))
(parse-pem-file in)))
まぁ、使い捨てのスクリプトとしては短めに書ける方ではないだろうか。よく言えばこの辺りを処理をするライブラリがそろっていると。というか、そんなライブラリくらいしかないのだが。偏りが激しい。ちょっと手を入れれば、RSAの公開鍵と秘密鍵も読めるようになる。けど、今のところいらないので無視。
2012-04-19
鈍足な正規表現だった・・・
なんとなく正規表現のベンチマークをGauche (0.9.2)、mosh (0.2.7)、Sagittarus(HEAD)の3つでとってみた。
正規表現は以下のページのものを使用。
思い立ったが吉日 (正規表現・続き) - Island Life
まぁ、結果はGaucheより速く、moshより遅いといったもの。moshは鬼車を使っているので、鬼車が速いのだろう。ただ、Gaucheは次のバージョンで速くなるらしいので、Sagittariusは鈍足な正規表現を持っていることになる。(特に最適化してないし、リニアタイムであることくらいしか保障してないからしょうがないのだが)。
どうでもいいのだけど、string output portとbytevector output portの実装が今まで腐っていたので直した。というか、上記のコードを移植するに当たって、直さないとメモリが尽きるというあほみたいな問題があった。単純な修正だが結構効果があって、bytevector output portで約2倍の速度を出すようになった。メモリも無駄に枯渇するということもなくなったので、いいことだ。
正規表現は以下のページのものを使用。
思い立ったが吉日 (正規表現・続き) - Island Life
まぁ、結果はGaucheより速く、moshより遅いといったもの。moshは鬼車を使っているので、鬼車が速いのだろう。ただ、Gaucheは次のバージョンで速くなるらしいので、Sagittariusは鈍足な正規表現を持っていることになる。(特に最適化してないし、リニアタイムであることくらいしか保障してないからしょうがないのだが)。
どうでもいいのだけど、string output portとbytevector output portの実装が今まで腐っていたので直した。というか、上記のコードを移植するに当たって、直さないとメモリが尽きるというあほみたいな問題があった。単純な修正だが結構効果があって、bytevector output portで約2倍の速度を出すようになった。メモリも無駄に枯渇するということもなくなったので、いいことだ。
JSP2.1と2.2の非互換ではまったこと
基本的には2.1→2.2でなんら問題は起きないはずなんだけど、起きた。しかも、解決方法みつからずの難問。
まずは以下のコードを見てほしい。
問題はこのBeanをJSPで使うと起きるのである。 以下がJSP。Fooのインスタンスfooをどっかから受け取っているという前提。
どうしたか?直接Javaコードを書きなぐりましたよ・・・
開発環境をTomcat 6からTomcat 7にしたら発生した逃げ場のない不具合。そりゃTomcat 7だけサポートするなら別に問題ないんだけど、他のサーバー(JBossとか)がどのバージョンのJSPをサポートしているか分からないので、どれでも動くようにする必要があるんだよ・・・なんでJavaにはCみたいなマクロがないんだろう。バージョン違いの非互換をどうにかする方法がないなんて・・・
まずは以下のコードを見てほしい。
public class Foo implements Serializable {
public FooEnum getEnum() {
return new FooEnum();
}
}
一見なんの変哲もないBeanである。実際何の変哲もない(勘のいい方はもう気づいたかも・・・)。問題はこのBeanをJSPで使うと起きるのである。 以下がJSP。Fooのインスタンスfooをどっかから受け取っているという前提。
${foo.enum}
これ、JSP2.1ではOKで、JSP2.2ではNG。理由は'enum'は識別子として認識しないから。JSP2.2で書きたかったら以下のように直接メソッドを呼ぶ必要がある。
${foo.getEnum()}
問題はJSP2.1はメソッドの直接呼出しをサポートしていないということ。つまり、JSP2.1で合法にすると、JSP2.2では非合法になる。逆も同様。逃げ場なし。どうしたか?直接Javaコードを書きなぐりましたよ・・・
開発環境をTomcat 6からTomcat 7にしたら発生した逃げ場のない不具合。そりゃTomcat 7だけサポートするなら別に問題ないんだけど、他のサーバー(JBossとか)がどのバージョンのJSPをサポートしているか分からないので、どれでも動くようにする必要があるんだよ・・・なんでJavaにはCみたいなマクロがないんだろう。バージョン違いの非互換をどうにかする方法がないなんて・・・
2012-04-18
やっつけ仕事
に近い感じではあるのだが、キャッシュの実装が終わった。思ったより時間がかからなかったなぁ。
とりあえず、正規表現(Cの実装)とSRFI-4(Schemeの実装)で両方とも動いているのを確認。キャッシュ用のAPIを追加して、ごにょごにょ。追加で、コンパイル時の定数畳み込みにキャッシュ可能かの判定を追加。これで、define-constantにうっかりハッシュテーブル(キャッシュできない!)とか書いてもキャッシュを壊すことがなくなった。
問題になるとすれば、複雑な構造を持つオブジェクトのテストは全然してないので、いろいろ足りないかもしれない。まぁ、そんな物をリーダーマクロで書くなんてことしないだろう。
しかし、キャッシュのソースがひどいことになっている。リファクタリングくらいはしたいなぁ。でも迂闊に手を入れたくもないなぁ・・・
とりあえず、正規表現(Cの実装)とSRFI-4(Schemeの実装)で両方とも動いているのを確認。キャッシュ用のAPIを追加して、ごにょごにょ。追加で、コンパイル時の定数畳み込みにキャッシュ可能かの判定を追加。これで、define-constantにうっかりハッシュテーブル(キャッシュできない!)とか書いてもキャッシュを壊すことがなくなった。
問題になるとすれば、複雑な構造を持つオブジェクトのテストは全然してないので、いろいろ足りないかもしれない。まぁ、そんな物をリーダーマクロで書くなんてことしないだろう。
しかし、キャッシュのソースがひどいことになっている。リファクタリングくらいはしたいなぁ。でも迂闊に手を入れたくもないなぁ・・・
cachable or cacheable?
何の気なしにずっと「cachable」という単語を使っていたのだが(造語だと自分では思っていた)、これって辞書もしくは標準があるのかとググッて見た。したら、「cachable」と「cacheable」が一応あるっぽい。
なんか1997年くらいに議論されている。Spelling of "cachable"
どうやらWiktionaryではcacheableみたい。cacheable
1995年に現れた単語みたい。Weblio
JEE6ではcacheableというクラスがある。
どうやら主流は最初の議論(メーリングリスト)で推されているcachableではなくcacheableっぽいなぁ。直すの面倒だし、僕は造語の方で。
どうやら、W3C的にはcacheableみたい。Standardize "cachable" and "cacheable" to "cacheable"
知るか!
なんか1997年くらいに議論されている。Spelling of "cachable"
どうやらWiktionaryではcacheableみたい。cacheable
1995年に現れた単語みたい。Weblio
JEE6ではcacheableというクラスがある。
どうやら主流は最初の議論(メーリングリスト)で推されているcachableではなくcacheableっぽいなぁ。直すの面倒だし、僕は造語の方で。
どうやら、W3C的にはcacheableみたい。Standardize "cachable" and "cacheable" to "cacheable"
知るか!
キャッシュの改善をしたい
前に書いたのだが、ちょっとソースを眺めなおした結果一筋縄ではいかなさそうだなぁと思い再びメモ。
とりあえず作成と読み込みのプロセスがある。っで、問題は作成時だと思われる。読み込みは単にタグみてオブジェクト作ってるだけなので。
【作成時のプロセス】
改善における現状見えている問題はスキャンをどうするかということ。現状では対象になるのは、シンボル、文字列、キーワード、識別子、マクロ、ペア、ベクタとクロージャである。最初の3つを除いたものは、自身の中に共有構造を持つ可能性があるオブジェクトを持っている。たとえば、識別子はそれ自身の中に環境を保持しているが、その環境の中にはペアとかベクタが入ってくる。C側、Scheme側でそれぞれ問題が出てはくるのだが、C側の方が問題の解決は楽だろう。
現状Cで書かれているオブジェクトでキャッシュしたいものは、文字セット、正規表現と日付くらいか。特に正規表現はリーダーマクロが単にS式を返すので多少効率が悪い。これがキャッシュ可能になれば、読み込み時にオブジェクトをそのまま返すということができるようになるため、正規表現使用時のパフォーマンスがあがる(多分)。残りはdefine-constantでも使わない限りはあまり恩恵がない。(コンパイル時の畳み込みをキャッシュ不可能なオブジェクトは除外するように直さないとなぁ・・・)
とりあえずC側の改善を試みて、後にScheme側に取り掛かるべきだろうか・・・
とりあえず作成と読み込みのプロセスがある。っで、問題は作成時だと思われる。読み込みは単にタグみてオブジェクト作ってるだけなので。
【作成時のプロセス】
- コンパイルされたコードのスキャン
- スキャン時に検出できたライブラリの書き出し
- コード本体の書き出し
- マクロのスキャン
- マクロの書き出し
改善における現状見えている問題はスキャンをどうするかということ。現状では対象になるのは、シンボル、文字列、キーワード、識別子、マクロ、ペア、ベクタとクロージャである。最初の3つを除いたものは、自身の中に共有構造を持つ可能性があるオブジェクトを持っている。たとえば、識別子はそれ自身の中に環境を保持しているが、その環境の中にはペアとかベクタが入ってくる。C側、Scheme側でそれぞれ問題が出てはくるのだが、C側の方が問題の解決は楽だろう。
現状Cで書かれているオブジェクトでキャッシュしたいものは、文字セット、正規表現と日付くらいか。特に正規表現はリーダーマクロが単にS式を返すので多少効率が悪い。これがキャッシュ可能になれば、読み込み時にオブジェクトをそのまま返すということができるようになるため、正規表現使用時のパフォーマンスがあがる(多分)。残りはdefine-constantでも使わない限りはあまり恩恵がない。(コンパイル時の畳み込みをキャッシュ不可能なオブジェクトは除外するように直さないとなぁ・・・)
とりあえずC側の改善を試みて、後にScheme側に取り掛かるべきだろうか・・・
2012-04-17
hierarchy
Twitterでこんなことを呟いたら、突っ込まれたのでネタにする。
ネタを書く前にまず、僕の中でhierarchy(ヒエラルキー)という言葉のイメージを説明しておく必要がある。(これが長くなるのでブログにした)
僕の中でのhierarchy意味は、トップダウン型の階層である。これは恐らく日本語ではヒエラルキーなんて言葉を使っていなかったのと、プログラム関連から意味が入ったこと、またこっちではその意味でしか使わないことがあるだろう。例えばカーストのヒエラルキーとか、食物連鎖のヒエラルキーとかはまぁ意味が分かる。個人的には日本訳がある言葉をわざわざカタカナで書く必要はないだろうと思うのだが。インテリの考えることは分からん。
っで、美醜のヒエラルキーという言葉を何を見たときに意味が取れなかった。何のこと?考えて、階層転じてランクのことかなぁととりあえず流してTwitterで呟いたと。
まぁ、これだけでは1000見て1違うから意味が複数あるというのもおかしいなぁと思い、Google先生でヒエラルキーを調べてみた。関連ワードで既に意味の分からないもの発見したので、まぁ誤用も一般的なんだろう。
意味の分からなかったもの。
顔面ヒエラルキーはGoogle検索の2、3ページあたりの検索結果で、あとは関連ワード。どれも階層と訳して意味が通じない、少なくとも僕の中では。構造だと、公正価格あたりはいけるかも。
最初に挙げた美醜に関してはどちらで訳しても意味が通じない。美醜というひどく抽象的な概念に対して、hierarchyというより具体的なものを指す単語を当てているのでイメージがまったくつかめないというのが理由だろう。訳語を当てても、「美醜の階層」もしくは「美醜の構造」となり意味不明である。(原文でどのように使われていたのか思い出せないので、ひょっとしたら前後のつながりでいけるのかもしれないが。)
そういえば、ダーリンの頭の中(母親が持っていた)にあった、テンションと似た感じかもしれない。英語ではテンションは「張る」ものだが、日本語では「上がる」ものだったりする。
どうでもいいのだが、ヒエラルキーという発音はどこから来たんだろう?ラテン語かな?英語だと、「ハイエラキー」に近いと思うのだが。
ネタを書く前にまず、僕の中でhierarchy(ヒエラルキー)という言葉のイメージを説明しておく必要がある。(これが長くなるのでブログにした)
僕の中でのhierarchy意味は、トップダウン型の階層である。これは恐らく日本語ではヒエラルキーなんて言葉を使っていなかったのと、プログラム関連から意味が入ったこと、またこっちではその意味でしか使わないことがあるだろう。例えばカーストのヒエラルキーとか、食物連鎖のヒエラルキーとかはまぁ意味が分かる。個人的には日本訳がある言葉をわざわざカタカナで書く必要はないだろうと思うのだが。インテリの考えることは分からん。
っで、美醜のヒエラルキーという言葉を何を見たときに意味が取れなかった。何のこと?考えて、階層転じてランクのことかなぁととりあえず流してTwitterで呟いたと。
まぁ、これだけでは1000見て1違うから意味が複数あるというのもおかしいなぁと思い、Google先生でヒエラルキーを調べてみた。関連ワードで既に意味の分からないもの発見したので、まぁ誤用も一般的なんだろう。
意味の分からなかったもの。
- 幸福の科学ヒエラルキー
- 天使ヒエラルキー
- 顔面ヒエラルキー(※)
- 公正価格ヒエラルキー
顔面ヒエラルキーはGoogle検索の2、3ページあたりの検索結果で、あとは関連ワード。どれも階層と訳して意味が通じない、少なくとも僕の中では。構造だと、公正価格あたりはいけるかも。
最初に挙げた美醜に関してはどちらで訳しても意味が通じない。美醜というひどく抽象的な概念に対して、hierarchyというより具体的なものを指す単語を当てているのでイメージがまったくつかめないというのが理由だろう。訳語を当てても、「美醜の階層」もしくは「美醜の構造」となり意味不明である。(原文でどのように使われていたのか思い出せないので、ひょっとしたら前後のつながりでいけるのかもしれないが。)
そういえば、ダーリンの頭の中(母親が持っていた)にあった、テンションと似た感じかもしれない。英語ではテンションは「張る」ものだが、日本語では「上がる」ものだったりする。
どうでもいいのだが、ヒエラルキーという発音はどこから来たんだろう?ラテン語かな?英語だと、「ハイエラキー」に近いと思うのだが。
2012-04-16
Sagittarius 0.3.1リリース
そろそろ月1のリリースがきつくなってきた。そして、意味があるような気がしなくなってきた。
今回のリリースはメンテナンスリリースです。
修正された不具合
今回のリリースはメンテナンスリリースです。
修正された不具合
- パターン変数がライブラリを超えられない不具合が修正されました。
- define-library構文がcond-expandを認識しない不具合が修正されました。
- "\x0;"が正しく読まれない不具合が修正されました。
- bytevector-s64-(native-)-set!が#x-8000000000000000に対してエラーを投げる不具合が修正されました。
- make-vectorにfill引数を与えなかった際に未定義値ではない値がセットされる不具合が修正されました。
- 暗号ライブラリ及び数学ライブラリの一部が書き直されました。これによってユーザー定義のCipher及びハッシュ関数を既存のAPIで使用することが可能になりました。
- ASN.1ライブラリが大幅に書き直されました。
- define-class構文が:metaclassオプションを受け取ることができるようになりました。
- SRFI-4ライブラリ(srfi :4)が追加されました。
- HMACライブラリ(rfc hmac)が追加されました。ただしMACの検証はできません。
- PKCS#5及びPKCS#12ライブラリ(rsa pkcs :5)、(rsa pkcs :12)が追加されました。PKCS#12はドキュメント化されていません。
- バイトベクタライブラリ(util bytevector)が追加されました。
Visual StudioでGDBっぽいWatch
WindbgではできなさそうなのでとりあえずVS2010ExpressEditionで。
以下のサイトを参考に。
Data break pointという言葉が分かればGoogle先生に伺いやすい。ということで伺ってみたら、Windbgにもあった。GUIから設定できるかまでは探していないが、baコマンドでいけるっぽい。
とりあえず、分かったこと。
やっぱり語回収されているっぽい。メモリを書き換えているのはGCのreclameという関数だった。Cygwinと同じようなことをしないと駄目なんだろう。どうやればいいんだろう?
以下のサイトを参考に。
指定のアドレスのメモリが変化したらブレークするブレークポイントを作成する - メモブロ
Data break pointという言葉が分かればGoogle先生に伺いやすい。ということで伺ってみたら、Windbgにもあった。GUIから設定できるかまでは探していないが、baコマンドでいけるっぽい。
とりあえず、分かったこと。
やっぱり語回収されているっぽい。メモリを書き換えているのはGCのreclameという関数だった。Cygwinと同じようなことをしないと駄目なんだろう。どうやればいいんだろう?
2012-04-15
Meetup
Trying to be active.
と称してLeidenのシーボルト博物館meetupに行ってみた。Salon - Japanese Talk in Amsterdamというmeetupなのだけど、なぜかアムスではなくライデン。単にたまには日本語を喋りたいと思ったのが参加した主な理由だが、当てが外れた。日本人僕一人、あとはフランス人とスペイン人(発案者は何人だろう?オランダ人っぽくなかったなぁ)。話した日本語0、あれ?
特に収穫というものもなく、切ない思いをした。
ここからも、どうでもいい話:
フランス人(特にパリ辺り)では日本の文化を学びたい人が多いらしい。その理由は、テレビでは日本のアニメが流れ、ゲームは日本の物が流行り(何かは知らない。FFとかテイルズかと)、漫画は言うまでもないという状態だから。つまり、オタクであるほど日本に興味を持つっぽい。話の中で出てきたアニメと漫画がすべて分かった自分もそっち方面だと自覚してるさ・・・今まで聞いた日本のイメージって、オタクかロボットしかないんだけどどういうことだろう?
オランダにはいわゆるカルチャースクールみたいなものが少ないらしい。そこにいた人の意見ではオランダ人は特に趣味が無く、エロ話してバーでビール飲めたらいいじゃんってイメージらしい。概ね同感だが・・・
フランス人は週に35時間しか働かなくてもいい上に休暇もたくさんあるというのは単なる伝説らしい。公務員はそうだけど、普通の企業の人は普通らしい。(まぁ、それでもヨーロッパ基準の普通なので日本に比べればはるかにましだろう)。
と称してLeidenのシーボルト博物館meetupに行ってみた。Salon - Japanese Talk in Amsterdamというmeetupなのだけど、なぜかアムスではなくライデン。単にたまには日本語を喋りたいと思ったのが参加した主な理由だが、当てが外れた。日本人僕一人、あとはフランス人とスペイン人(発案者は何人だろう?オランダ人っぽくなかったなぁ)。話した日本語0、あれ?
特に収穫というものもなく、切ない思いをした。
ここからも、どうでもいい話:
フランス人(特にパリ辺り)では日本の文化を学びたい人が多いらしい。その理由は、テレビでは日本のアニメが流れ、ゲームは日本の物が流行り(何かは知らない。FFとかテイルズかと)、漫画は言うまでもないという状態だから。つまり、オタクであるほど日本に興味を持つっぽい。話の中で出てきたアニメと漫画がすべて分かった自分もそっち方面だと自覚してるさ・・・今まで聞いた日本のイメージって、オタクかロボットしかないんだけどどういうことだろう?
オランダにはいわゆるカルチャースクールみたいなものが少ないらしい。そこにいた人の意見ではオランダ人は特に趣味が無く、エロ話してバーでビール飲めたらいいじゃんってイメージらしい。概ね同感だが・・・
フランス人は週に35時間しか働かなくてもいい上に休暇もたくさんあるというのは単なる伝説らしい。公務員はそうだけど、普通の企業の人は普通らしい。(まぁ、それでもヨーロッパ基準の普通なので日本に比べればはるかにましだろう)。
2012-04-14
君をつれて
2002年にDVD化された天空の城ラピュタの16年後のパズーの心境を石井竜也が歌ったとされるもの。ちなみに、天空の城ラピュタは数少ない何時見ても感動できる作品に一つだと思っている。(竜の巣へ入る際のデジタルリマスタリングは正直邪魔だと思っているが・・・)
話が逸れた。物語の中でパズーとシータの年齢は明かされていないが、恐らく14、15歳くらいだと思う。その16年後なので、30歳くらいのパズーを歌った歌ということになる。ただ追い求めるだけの少年から守るものが出来、それでも君と一緒にまた旅に出たいという大人の視点な歌詞だと思う。(国語苦手・・・)
歌が作られたのは今から10年前だけど、僕の年齢がちょうど歌の歌詞とマッチするなぁと思って書いていたりする。すごく分かるなぁというのが感想なのだが、それと同時に大人になるということは夢を見ているだけでの少年ではいられなくなるということなんだなぁと実感した。無数にある可能性という枝の中で望むと望まざると選択せざるを得ず、現実という名の下に刈り取られた無数の夢、それらを受け入れてなおまた旅に出たいあの頃のように。なんて感じたのはまぁ、きっと自分の中にそんなことを考えている部分があるのだろう。
希望に満ちた天を突かんばかりの摩天楼の群れだったこの世界は、お前の身近にあった小さな街の風景になりさがった。From Bleach(あってる?)
最終的には何になるんだろう。今は住んでるアパートかね。脱出ゲームばりに。
話が逸れた。物語の中でパズーとシータの年齢は明かされていないが、恐らく14、15歳くらいだと思う。その16年後なので、30歳くらいのパズーを歌った歌ということになる。ただ追い求めるだけの少年から守るものが出来、それでも君と一緒にまた旅に出たいという大人の視点な歌詞だと思う。(国語苦手・・・)
歌が作られたのは今から10年前だけど、僕の年齢がちょうど歌の歌詞とマッチするなぁと思って書いていたりする。すごく分かるなぁというのが感想なのだが、それと同時に大人になるということは夢を見ているだけでの少年ではいられなくなるということなんだなぁと実感した。無数にある可能性という枝の中で望むと望まざると選択せざるを得ず、現実という名の下に刈り取られた無数の夢、それらを受け入れてなおまた旅に出たいあの頃のように。なんて感じたのはまぁ、きっと自分の中にそんなことを考えている部分があるのだろう。
希望に満ちた天を突かんばかりの摩天楼の群れだったこの世界は、お前の身近にあった小さな街の風景になりさがった。From Bleach(あってる?)
最終的には何になるんだろう。今は住んでるアパートかね。脱出ゲームばりに。
2012-04-13
Windowsをサポートするということ
割と茨の道だと思えてきた。
何が起きたか。
多分GC関連の不具合。以前Cygwinで似たようなことが起きたので。
なにそれ?
動的にリンクされるモジュール内で割り当てられたメモリが誤回収されているっぽい(値が勝手に書き換わっている)。
Cygwinではルートを追加してやることで回避したんだけど、Windowsではどうやってやるんだろう?最新版のGCでは解決されているのだろうか?(それにしても、7.2-Alpha6からちっとも次が出ないなぁ)
そもそもほとんどダウンロードされていないプログラムなんだから別にサポートする必要ないじゃんとか思っていたのだが、自分がWindows版を普通に使っている現実があってごにょごにょ・・・
何が起きたか。
多分GC関連の不具合。以前Cygwinで似たようなことが起きたので。
なにそれ?
動的にリンクされるモジュール内で割り当てられたメモリが誤回収されているっぽい(値が勝手に書き換わっている)。
Cygwinではルートを追加してやることで回避したんだけど、Windowsではどうやってやるんだろう?最新版のGCでは解決されているのだろうか?(それにしても、7.2-Alpha6からちっとも次が出ないなぁ)
そもそもほとんどダウンロードされていないプログラムなんだから別にサポートする必要ないじゃんとか思っていたのだが、自分がWindows版を普通に使っている現実があってごにょごにょ・・・
2012-04-10
Memo: Cache reader improvement
Since Sagittarius supports SRFI-4 (well, it's not released yet), the cache reading problem is totally floated up.
Before I describe the problem, I need to write how exactly the cache mechanism works. The reason why Sagittarius has cache is because of performance improvement. Let's say when (rnrs) library is loaded, then related libraries are also loaded (of course). However Sagittarius does not have compiled base library like Ypsilon and mosh have. So each time these library are loaded, compiler is also invoked. This caused really bad performance problem. So I introduced the cache mechanism.
However it is not completely done and I was searching what is the better solution for it. Right now, when Sagittarius load a library, it tries to find the cache first and if it can not find then compile the real library and write its cache.
Then what if there is a non cachable object in the compiled code. Yes, this is the problem. You can simply try how to make invalid cache code. Write a reader macro and let it return a hashtable (yes, even hashtable can not be cached.) Current implementation has no space to expand the behaviour.
What I am thinking is adding two slots to base classes like 'readCache' and 'writeCache'. It is possible since Sagittarius has supported CLOS. Then introduce <fasl> class to allow user to write own cache reader. I am planing to implement this in 0.3.2 but I'm not sure if I can...
Before I describe the problem, I need to write how exactly the cache mechanism works. The reason why Sagittarius has cache is because of performance improvement. Let's say when (rnrs) library is loaded, then related libraries are also loaded (of course). However Sagittarius does not have compiled base library like Ypsilon and mosh have. So each time these library are loaded, compiler is also invoked. This caused really bad performance problem. So I introduced the cache mechanism.
However it is not completely done and I was searching what is the better solution for it. Right now, when Sagittarius load a library, it tries to find the cache first and if it can not find then compile the real library and write its cache.
Then what if there is a non cachable object in the compiled code. Yes, this is the problem. You can simply try how to make invalid cache code. Write a reader macro and let it return a hashtable (yes, even hashtable can not be cached.) Current implementation has no space to expand the behaviour.
What I am thinking is adding two slots to base classes like 'readCache' and 'writeCache'. It is possible since Sagittarius has supported CLOS. Then introduce <fasl> class to allow user to write own cache reader. I am planing to implement this in 0.3.2 but I'm not sure if I can...
2012-04-09
チラシの裏
そもそもこのブログ自体がチラシの裏なので更に裏返したら表になってしまう(わけない)。
単にどこかに吐き出さないと精神衛生上よろしくないなぁというだけで別に誰かに読んでほしいとかそんな意図はさらさらない話題。
2月くらいに元彼女と別れたのだが(まぁ去年の12月くらいから関係は最悪だったが・・・)、まぁいろいろ物が残っていたり宅配が未だにこっちに来たりとなんだかんだで顔を合わせる機会が多い。そのたびにものすごいストレスが掛かる。別に話すことは何もないし、向こうもこちらも何かを何かをするわけではないのだが、扉が開く音を聞くだけで体が硬直する感じ。
理由はまぁいろいろあるんだけど、散々人格否定されてダメ人間の烙印押されたものだから勝手に体が防戦体制に入るんだろうね。正直ここから逃げ出したい気分に1ヶ月の80%くらいはなっていたりする。もうなんかうっかり街中で遭遇するんじゃないかっていうのすら心配になる。
年収600万以上+残業代その他別支給な仕事ないだろうか・・・日本に帰ってもいいかなぁと本気で考えていたりする・・・
しかし、アレだけ人を罵っておいてしれっとした態度が出来るっていうのは一体どんな精神構造してるんだろうね。 正直、嫌悪感丸出しで目も合わせたくないみたいな感じの方が100倍気が楽だ。こっちも単に敵としてみればいいだけなんだし。
単にどこかに吐き出さないと精神衛生上よろしくないなぁというだけで別に誰かに読んでほしいとかそんな意図はさらさらない話題。
2月くらいに元彼女と別れたのだが(まぁ去年の12月くらいから関係は最悪だったが・・・)、まぁいろいろ物が残っていたり宅配が未だにこっちに来たりとなんだかんだで顔を合わせる機会が多い。そのたびにものすごいストレスが掛かる。別に話すことは何もないし、向こうもこちらも何かを何かをするわけではないのだが、扉が開く音を聞くだけで体が硬直する感じ。
理由はまぁいろいろあるんだけど、散々人格否定されてダメ人間の烙印押されたものだから勝手に体が防戦体制に入るんだろうね。正直ここから逃げ出したい気分に1ヶ月の80%くらいはなっていたりする。もうなんかうっかり街中で遭遇するんじゃないかっていうのすら心配になる。
年収600万以上+残業代その他別支給な仕事ないだろうか・・・日本に帰ってもいいかなぁと本気で考えていたりする・・・
しかし、アレだけ人を罵っておいてしれっとした態度が出来るっていうのは一体どんな精神構造してるんだろうね。 正直、嫌悪感丸出しで目も合わせたくないみたいな感じの方が100倍気が楽だ。こっちも単に敵としてみればいいだけなんだし。
2e paasdag
標題はオランダ語。意味は2nd Easter day。
今日はイースターの二日目。正直イースターがなんだか分かってはいないのだが(キリスト教の何かだということは知っている)、オランダでは今日は休日になる。
だから何ということはないのだが、何をしていいのか分からないくらい暇。PKCS#12周りのコードは会社に全部置いてあるので何もできない。(仕事でP12ファイルの中身確認に使っているので。ついでに、P12ファイルなんて手元にない)。
天気も悪いし、どうしたものかね・・・
今日はイースターの二日目。正直イースターがなんだか分かってはいないのだが(キリスト教の何かだということは知っている)、オランダでは今日は休日になる。
だから何ということはないのだが、何をしていいのか分からないくらい暇。PKCS#12周りのコードは会社に全部置いてあるので何もできない。(仕事でP12ファイルの中身確認に使っているので。ついでに、P12ファイルなんて手元にない)。
天気も悪いし、どうしたものかね・・・
2012-04-06
R7RSの第5次投票
月刊R7RS - 第五次投票の結果が出る - .mjtの日記復帰計画を見て出たんだとチェック。
正直R7RSサポートと称してドラフト5対応にしたのは時期尚早だったなぁと激しく反省した。所詮はドラフト、いくつ出ようが大きく変わるものだ・・・
大き目な変更点(Cレベルで変更が必要なもの):
正直R7RSサポートと称してドラフト5対応にしたのは時期尚早だったなぁと激しく反省した。所詮はドラフト、いくつ出ようが大きく変わるものだ・・・
大き目な変更点(Cレベルで変更が必要なもの):
- ベクタがセルクオートになった。
- シンボルのエスケープが変わった。\x..;は中で見る必要がなくなった。
SRFI-4 has been supported
I have wrote a library which supports SRFI-4. This might be the very first library using reader macro from Scheme. (I don't remember if I have already written something before). Well, actually R6RS already has bytevector to handle these homogeneous numeric vectors, however it is sometimes convenient if I can write
The reason why I wanted this is really simple. When I want to read a byte array dumped from Java, it is convenient to be able to write it. (Well, if I dump it, I can convert it to unsigned. But if I peek it from debugger, byte in Java is signed. I really hate this). I actually didn't have any intention to make it a library but when I wrote the reader macro, I thought I will write this again if I don't make the library.
Why is it #s8 instead of #vs8?
Implementation restriction... #vs8 was too long for dispatch macro and if I did it, I also need to rewrite existed bytevector reader.
#s8(-128 127 ...) instead of #vu8(255 127 ...). So now, I can write like this.#<(srfi :4)> ;; enable the reader macro (import (rnrs) (srfi :4)) (define s8 #s8(-128 127)) ;; #s8(...) is reader macro (display s8) (newline) ;; prints #s8(-128 127) (s8vector-set! s8 0 1) ;; unspecified (s8vector-ref s8 0) ;; returns 1 (s8vector-set! s8 0 -128) ;; unspecified (s8vector->list s8) ;; (-128 127) (list->s8vector '(1 2));; #s8(1 2) (bytevector? s8) ;; #fThe homogeneous vectors are not bytevector defined in R6RS. So
bytevector? returns #f. Maybe I will write a conversion procedure someday. The reason why I wanted this is really simple. When I want to read a byte array dumped from Java, it is convenient to be able to write it. (Well, if I dump it, I can convert it to unsigned. But if I peek it from debugger, byte in Java is signed. I really hate this). I actually didn't have any intention to make it a library but when I wrote the reader macro, I thought I will write this again if I don't make the library.
Why is it #s8 instead of #vs8?
Implementation restriction... #vs8 was too long for dispatch macro and if I did it, I also need to rewrite existed bytevector reader.
2012-04-03
PBEのCipher
いまいち上手くいかない。HMAC、派生鍵は動いているので後はここだけなのだが・・・
上記の2つが動いているのでナイーブな(正しくない)実装は動いているように見える。パスワードを与えて暗号化、複合化は出来ているということだ。
では何が問題か。同一のアルゴリズム、鍵、パラメータを使用した場合、JCEだろうが何だろうが同一の暗号結果を返さなければならない、という部分。俺々仕様ではダメなのが辛い。
一応BouncyCastleの実装も見てみたんだけど、恐らく初期ベクタの与え方が拙いと思われる。 ただ、実装を見た感じ、ブロックサイズのバイトを0で初期化しただけにしか見えないんだけどなぁ・・・派生鍵の部分で見落としがあるだろうか?回転数が違ってるとか。さすがにDESのCBCモードを自前で実装する気にはなれないのでどうしたものだろう。
どこかにPBEWithMD5DES辺りのサンプル(もしくは内部で何してるかの解説、仕様書)ないかな・・・
(ひょっとしてこれだとHMAC要らないってことないよね?・・・)
上記の2つが動いているのでナイーブな(正しくない)実装は動いているように見える。パスワードを与えて暗号化、複合化は出来ているということだ。
では何が問題か。同一のアルゴリズム、鍵、パラメータを使用した場合、JCEだろうが何だろうが同一の暗号結果を返さなければならない、という部分。俺々仕様ではダメなのが辛い。
一応BouncyCastleの実装も見てみたんだけど、恐らく初期ベクタの与え方が拙いと思われる。 ただ、実装を見た感じ、ブロックサイズのバイトを0で初期化しただけにしか見えないんだけどなぁ・・・派生鍵の部分で見落としがあるだろうか?回転数が違ってるとか。さすがにDESのCBCモードを自前で実装する気にはなれないのでどうしたものだろう。
どこかにPBEWithMD5DES辺りのサンプル(もしくは内部で何してるかの解説、仕様書)ないかな・・・
(ひょっとしてこれだとHMAC要らないってことないよね?・・・)
2012-03-31
死刑廃止論
Twitterでリツイートされていた記事を読んで感じたこと。
元記事はこれ:「自分の子どもが殺されても 同じことが言えるのか」と 書いた人に訊きたい
多少批判的なことをを書くので、その前に自分の立場を明確にしておこうと思う。僕は死刑賛成論者である。理由は「凶悪犯罪を犯したものの再犯率を考えれば死刑にした方がよい」というもの。性悪説支持とも言えるか?そもそも、日本で死刑を求刑されるほどの犯罪ってかなりの凶悪犯罪だった気がする(うろ覚え)。なので、同規模の犯罪を再犯されるよりは、そいつの命1つ奪っておいた方が社会的に利益が大きいだろうというもの。別に人は更生できないと言っているつもりはない。また、上記の記事にあったような「被害者家族のことを考えろ」というものではない。
この記事を読んでまず思ったのはちょっとコメントを恣意的に拾いすぎだろうというもの。僕は勝間和代という人がどんな人か知らない。ひょっとしたらいわゆるプロ市民、極左な人であまり世間でいい評判が無いために何を言っても批判、罵倒を浴びる人なのかもしれない。また、その動画を見ていないので本当にそんな意見ばかりが流れたのかも知らない。
最後まで記事を読んだ後に感じたのは、「著者は単に死刑賛成論者を批判したかっただけではないか」というもの。確かに言っていることは正論だし、まぁ筋も通っているなぁと思ったんだけど、問題なのは「自分がどちらの立場かを明確にしていない」ということ。ひょっとしたら冒頭の部分で反対論者であると言っているのかもしれないが、もしそうなら言い回しは非常に分かりにくく、あえてぼかしているように見える。しかも、最後に自分が当事者になったらスタンダードは変わるなんて言っている辺り、自分に降りかかる批判を避けているだけにしか見えない。
少なくともコメントを残した人は自分の主張をしているので、議論をするのであれば立場を明確にしないと話にならないのではないか?(あぁ、だから著者は反対論者で自分が当事者になったら賛成論者になると明言しているのか)
国語の成績は悪かったのでこの著者が「本当に言いたいこと」というのが読み取れていない可能性が高いが、理路整然(ともしていないが)と頭ごなしにコメントを残した人を非難しているように見えたので、なんとなく噛み付いてみた。
議論すべき問題だとは思うけど、この記事は持ってく方向がおかしい。 (そもそも議論ではないのか)
元記事はこれ:「自分の子どもが殺されても 同じことが言えるのか」と 書いた人に訊きたい
多少批判的なことをを書くので、その前に自分の立場を明確にしておこうと思う。僕は死刑賛成論者である。理由は「凶悪犯罪を犯したものの再犯率を考えれば死刑にした方がよい」というもの。性悪説支持とも言えるか?そもそも、日本で死刑を求刑されるほどの犯罪ってかなりの凶悪犯罪だった気がする(うろ覚え)。なので、同規模の犯罪を再犯されるよりは、そいつの命1つ奪っておいた方が社会的に利益が大きいだろうというもの。別に人は更生できないと言っているつもりはない。また、上記の記事にあったような「被害者家族のことを考えろ」というものではない。
この記事を読んでまず思ったのはちょっとコメントを恣意的に拾いすぎだろうというもの。僕は勝間和代という人がどんな人か知らない。ひょっとしたらいわゆるプロ市民、極左な人であまり世間でいい評判が無いために何を言っても批判、罵倒を浴びる人なのかもしれない。また、その動画を見ていないので本当にそんな意見ばかりが流れたのかも知らない。
最後まで記事を読んだ後に感じたのは、「著者は単に死刑賛成論者を批判したかっただけではないか」というもの。確かに言っていることは正論だし、まぁ筋も通っているなぁと思ったんだけど、問題なのは「自分がどちらの立場かを明確にしていない」ということ。ひょっとしたら冒頭の部分で反対論者であると言っているのかもしれないが、もしそうなら言い回しは非常に分かりにくく、あえてぼかしているように見える。しかも、最後に自分が当事者になったらスタンダードは変わるなんて言っている辺り、自分に降りかかる批判を避けているだけにしか見えない。
少なくともコメントを残した人は自分の主張をしているので、議論をするのであれば立場を明確にしないと話にならないのではないか?(あぁ、だから著者は反対論者で自分が当事者になったら賛成論者になると明言しているのか)
国語の成績は悪かったのでこの著者が「本当に言いたいこと」というのが読み取れていない可能性が高いが、理路整然(ともしていないが)と頭ごなしにコメントを残した人を非難しているように見えたので、なんとなく噛み付いてみた。
議論すべき問題だとは思うけど、この記事は持ってく方向がおかしい。 (そもそも議論ではないのか)
2012-03-27
署名と検証
Pure JavaScriptでRSA署名するソースを公開しちゃいますよ~~~~w
なんてのを見つけて、こりゃ手軽にSagittariusの(crypto)ライブラリ(というかRSAか)が上手く動いているか楽に検証できるや、と試してみた。
結論を言えば、上手く動いていそうなのだが、ちょっと戸惑った。(最初にX.509の証明書から公開鍵を引っ張り出す作業が必要だったが、まぁこれはいいか)
最初に試したのはデフォルトの挙動。これが戸惑った部分で、署名が毎回違う値になる。でも検証すると毎回OKがでる。上記のサイトは同一メッセージなら毎回同一の署名。
正直一瞬バグを疑ったが、よく考えてみると署名と検証で使うエンコーダとデコーダが指定できる作りになっているのを思い出した。っで、デフォルトだとPKCS #1 EMSA-PSS-ENCODEを使っていて、こいつはsalt入れて毎回違う値を吐き出すようになっている。(まぁ、その方が安全だしね)
っで、もう一つ実装してある、 PKCS v1.5 エンコーダを試してみたらまったく上記サイトと同じ値になった。どうやらよさげ。
っで、気になるのはx.509との兼ね合いを考えた際にどっちがいいんだろう?というもの。多分そのうちx.509の証明書を読み込めるようにするので、デフォルトでとりあえずx.509の方式にしておきたいなぁと。RFC読めということかな・・・
なんてのを見つけて、こりゃ手軽にSagittariusの(crypto)ライブラリ(というかRSAか)が上手く動いているか楽に検証できるや、と試してみた。
結論を言えば、上手く動いていそうなのだが、ちょっと戸惑った。(最初にX.509の証明書から公開鍵を引っ張り出す作業が必要だったが、まぁこれはいいか)
最初に試したのはデフォルトの挙動。これが戸惑った部分で、署名が毎回違う値になる。でも検証すると毎回OKがでる。上記のサイトは同一メッセージなら毎回同一の署名。
正直一瞬バグを疑ったが、よく考えてみると署名と検証で使うエンコーダとデコーダが指定できる作りになっているのを思い出した。っで、デフォルトだとPKCS #1 EMSA-PSS-ENCODEを使っていて、こいつはsalt入れて毎回違う値を吐き出すようになっている。(まぁ、その方が安全だしね)
っで、もう一つ実装してある、 PKCS v1.5 エンコーダを試してみたらまったく上記サイトと同じ値になった。どうやらよさげ。
っで、気になるのはx.509との兼ね合いを考えた際にどっちがいいんだろう?というもの。多分そのうちx.509の証明書を読み込めるようにするので、デフォルトでとりあえずx.509の方式にしておきたいなぁと。RFC読めということかな・・・
RFC2898(PKCS#5)斜め読み
斜め読みもしてないな、眺めただけか・・・
何が知りたかったかといえば、PBEが意味するところと、PKCS#5自体が暗号化のアルゴリズムを規定しないということ。実際そうだった。
では何を定義しているのかと言えば、(眺めただけなので違うかもしれないが)もう一つ上の層というか、より安全に暗号化する方法みたいなものと、とりあえずこいつに従っておけば中身は違っても表面上は何をしているかが統一できるといった感じのもの(だと思う)。
たとえば、派生鍵の作成手順とかその鍵を使った暗号化とかそんなの。でも派生鍵を作成する関数(KDF, Key Derivation Function)は外から渡す必要があるし、暗号化そのものを行う関数や、ハッシュ関数も外から渡す必要がある。 (もちろんMAC関数も)
嘘。KDFに関してはPBKDF1とPBKDF2がどういった関数であるけPKCS#5(RFC2898)内で定義されてた。MACも書いてある。さすがにハッシュ関数は別物だけど。
そうは言っても渡された関数に渡すパラメータとか統一できんよというために、関数が受け取るパラメータも定義してあって、その中にどのアルゴリズムを使うかを指定できるようになっている。まぁOIDでなわけだが。
問題にするところとしては、(crypto)ライブラリを書き直すもしくはてこ入れをするとして、このPKCS#5的に直すのか、とりあえずこういったものも実装しやすいように直すのかで大分方針が変わる気がする。後者かな。PKCS#5をサポートしたかったら(rfc pkcs :5)とか(pkcs :5)とか提供すればいいわけだし。ただ、派生鍵をどうするかは考えないと。こいつばっかりはアルゴリズムにどうしても依存するわけだし。(しないのか?調べないとなぁ)
どうでもいいけど、暗号関連の何かを読むと必ず「salt」って出てくるけど、塩って訳すと変だよなぁ。なんて訳すんだろう?
何が知りたかったかといえば、PBEが意味するところと、PKCS#5自体が暗号化のアルゴリズムを規定しないということ。実際そうだった。
では何を定義しているのかと言えば、(眺めただけなので違うかもしれないが)もう一つ上の層というか、より安全に暗号化する方法みたいなものと、とりあえずこいつに従っておけば中身は違っても表面上は何をしているかが統一できるといった感じのもの(だと思う)。
たとえば、派生鍵の作成手順とかその鍵を使った暗号化とかそんなの。
嘘。KDFに関してはPBKDF1とPBKDF2がどういった関数であるけPKCS#5(RFC2898)内で定義されてた。MACも書いてある。さすがにハッシュ関数は別物だけど。
そうは言っても渡された関数に渡すパラメータとか統一できんよというために、関数が受け取るパラメータも定義してあって、その中にどのアルゴリズムを使うかを指定できるようになっている。まぁOIDでなわけだが。
問題にするところとしては、(crypto)ライブラリを書き直すもしくはてこ入れをするとして、このPKCS#5的に直すのか、とりあえずこういったものも実装しやすいように直すのかで大分方針が変わる気がする。後者かな。PKCS#5をサポートしたかったら(rfc pkcs :5)とか(pkcs :5)とか提供すればいいわけだし。ただ、派生鍵をどうするかは考えないと。こいつばっかりはアルゴリズムにどうしても依存するわけだし。(しないのか?調べないとなぁ)
どうでもいいけど、暗号関連の何かを読むと必ず「salt」って出てくるけど、塩って訳すと変だよなぁ。なんて訳すんだろう?
2012-03-26
(crypto)ライブラリを見直したい
願望形・・・
何が問題かと言えば現状ではサポートしていないアルゴリズムはまったく扱えないということ。追加もできない。別にそれでいいじゃんと言えばそうなんだけど、せっかく抽象化しているのにサポートしてないものはべた書きでは面白くない。
ということで、APIを見ながら何がどうなればいいかということを考えてみることにする。
(しかし、結構でかいライブラリの割りに、口は少ないなぁ。いいことなのか?)
っで、どうしたいか。今回まずいなぁと思ったのは、PKCS#12のファイルを読み込む際にPBEが複号できないといけないのだが、(crypto)ライブラリではサポートされていない上にcipherを作ることも追加することもできない。 これはよろしくない。(元々はlibtomcryptの薄いラッパーのつもりだったし十分ではあったのだが)
とりあえず案としては、pimplみたいな感じで<cipher>と<cipher-spi>(名前はJCEから)クラスを作って、標準サポートに<builtin-cipher-spi>、ユーザーが追加したかったら<cipher-spi>を継承したクラスを作るという風にしたらいいだろうか。ちょっと考え方がJavaよりで、関数型ではないかもしれんが・・・
何が問題かと言えば現状ではサポートしていないアルゴリズムはまったく扱えないということ。追加もできない。別にそれでいいじゃんと言えばそうなんだけど、せっかく抽象化しているのにサポートしてないものはべた書きでは面白くない。
ということで、APIを見ながら何がどうなればいいかということを考えてみることにする。
- cipher
- アルゴリズムをラップしたCipherオブジェクトを返す。現状では与えられたCipherタイプが定義済みの共通鍵方式かどうかを判別している。(まずはこれか)
- encrypt
- decrypt
- Cで書かれたsubr。中身はやっぱり共通鍵かどうか見てディスパッチしてる
- signature
- verify
- Cで書かれたsubr。共通鍵ならエラーは上げる。Schemeで書かれたsignerとverifierを呼び出している。
(しかし、結構でかいライブラリの割りに、口は少ないなぁ。いいことなのか?)
っで、どうしたいか。今回まずいなぁと思ったのは、PKCS#12のファイルを読み込む際にPBEが複号できないといけないのだが、(crypto)ライブラリではサポートされていない上にcipherを作ることも追加することもできない。 これはよろしくない。(元々はlibtomcryptの薄いラッパーのつもりだったし十分ではあったのだが)
とりあえず案としては、pimplみたいな感じで<cipher>と<cipher-spi>(名前はJCEから)クラスを作って、標準サポートに<builtin-cipher-spi>、ユーザーが追加したかったら<cipher-spi>を継承したクラスを作るという風にしたらいいだろうか。ちょっと考え方がJavaよりで、関数型ではないかもしれんが・・・
2012-03-24
The catcher in the rye
多分このタイトルどこかにあると思うが。
街まで出る必要があったのと、さらに時間を潰す必要があったのでポケットに入るサイズの本を探したらこれかアリスしかなかっただけだが。
時間つぶしのためスタバ(オランダにもあるんですよ)に入ってコーヒーとアップルパイを貪りながら読んでた際にある一文が目に入ってすごく共感したなぁという話。 以下がその一文。
The catcher in the rye, chapter 2.
昔読んだときは正直それを突っぱねるHolden君に共感できなかったんだけど、今なら分かる部分がある。Spencer先生は最初に傷口に塩を塗りつけて、ほら君はこんなことをしたんだよ、なんでやったんだい?みたいに聞いていて、そりゃあ意固地にもなるわなぁと。実際自分もこれと似たようなことを何度も何度もやられたので。
ここで大人な対応でいろいろ受け入れられればいいんだろうけどそれが出来る人間ってどれくらいいるんだろう?
例えば仕事とかで何かミスを犯す度に上司から3年くらい前のことまでひっくり返されてネチネチ言われた挙句、「俺はお前を助けてやってるんだぞ」みたいなことを言われてさてどれくらい信じられるかと。
それでも仕事なら給料のためとか割り切れるけど、僕の場合はこれが人間関係だったので心が折れた。
久しぶりに読んだ本で昔は共感できなかった青臭い部分に共感している辺り、精神年齢が下がっているのだろう。もしくは大人になれてないか。
街まで出る必要があったのと、さらに時間を潰す必要があったのでポケットに入るサイズの本を探したらこれかアリスしかなかっただけだが。
時間つぶしのためスタバ(オランダにもあるんですよ)に入ってコーヒーとアップルパイを貪りながら読んでた際にある一文が目に入ってすごく共感したなぁという話。 以下がその一文。
The catcher in the rye, chapter 2.
"I'd like to put some sense in that head of yours, boy. I'm trying to help you. I'm trying to help you, if I can."最後の文がそれなんだけど、最初のSpencer先生の行からじゃないと意味不明なのでそこから引用。この前の部分で先生がHolden君に対して何でこんな解答をテストでしたんだみたいなのがあって、落第していくHolden君をなんとか救おうみたいな流れ。
He really was, too. You could see that. But it was just that we were too much opposite side of the pole, that's all.
昔読んだときは正直それを突っぱねるHolden君に共感できなかったんだけど、今なら分かる部分がある。Spencer先生は最初に傷口に塩を塗りつけて、ほら君はこんなことをしたんだよ、なんでやったんだい?みたいに聞いていて、そりゃあ意固地にもなるわなぁと。実際自分もこれと似たようなことを何度も何度もやられたので。
ここで大人な対応でいろいろ受け入れられればいいんだろうけどそれが出来る人間ってどれくらいいるんだろう?
例えば仕事とかで何かミスを犯す度に上司から3年くらい前のことまでひっくり返されてネチネチ言われた挙句、「俺はお前を助けてやってるんだぞ」みたいなことを言われてさてどれくらい信じられるかと。
それでも仕事なら給料のためとか割り切れるけど、僕の場合はこれが人間関係だったので心が折れた。
久しぶりに読んだ本で昔は共感できなかった青臭い部分に共感している辺り、精神年齢が下がっているのだろう。もしくは大人になれてないか。
2012-03-23
マルチスレッドテスト(結果)
連投だなぁ、まぁいいか。
多少の制約があるものの、まぁ元気に動いている感じ。っで、せっかくマルチに走らせているのだから、どれくらいパフォーマンスに影響が出たかというところが気になる。っで調べてみた。
実行環境: Cygwin on Windows 7 (64bits), Core i7
シングルスレッド
2倍速!CPUの使用量が200%を超えとる。やった甲斐ありと思っていいかな。
多少の制約があるものの、まぁ元気に動いている感じ。っで、せっかくマルチに走らせているのだから、どれくらいパフォーマンスに影響が出たかというところが気になる。っで調べてみた。
実行環境: Cygwin on Windows 7 (64bits), Core i7
シングルスレッド
% time sash run-test.scm sitelib ;; ログ省略 sash run-test.scm sitelib 3.99s user 0.25s system 99% cpu 4.243 totalマルチスレッド
% time sash run-test.scm sitelib ;; ログ省略 sash run-test.scm sitelib 4.79s user 0.25s system 252% cpu 1.997 total※ 実行スクリプト内を直接いじっているので、コマンドは一緒に見えるけど、中身は違う。
2倍速!CPUの使用量が200%を超えとる。やった甲斐ありと思っていいかな。
マルチスレッドテスト(依存関係問題)
昨日の変更で一度作成されたライブラリはグローバルに持つようにしたので、キャッシュを読み込むときに問題が起きるようになった。
問題としては(恐らくだが)、スレッドAがライブラリhogeをキャッシュから読み込んでいるときにスレッドBも同じライブラリを読み込むとどうなるかというもの。 現状だとキャッシュの読み込みには特にロックを取得していないので、データ読込→ライブラリ作成→データ復元→インポートという流れの中で問題が起きるのかなぁと(確証ない、状況証拠のみ)。
上記の仮定が正しいとして、解決方法を少し考えてみた。
マルチスレッドでloadを使うなんて事がそうあるとは思えないので、とりあえず2を実装してみればいいだろうか?
問題としては(恐らくだが)、スレッドAがライブラリhogeをキャッシュから読み込んでいるときにスレッドBも同じライブラリを読み込むとどうなるかというもの。 現状だとキャッシュの読み込みには特にロックを取得していないので、データ読込→ライブラリ作成→データ復元→インポートという流れの中で問題が起きるのかなぁと(確証ない、状況証拠のみ)。
上記の仮定が正しいとして、解決方法を少し考えてみた。
- キャッシュ読み込み時に、プロセスリストを作成し、そのリストの中に自分が必要としているキャッシュがあれば待つ。
でもこの場合同じライブラリだけど別ファイルだったらどうなるんだ?
- キャッシュ読み込み自体にロックをかけて、ライブラリが存在しているか確認、あれば帰る
マルチスレッドでloadを使うなんて事がそうあるとは思えないので、とりあえず2を実装してみればいいだろうか?
2012-03-22
マルチスレッドテスト(調査)
テストケースをファイルをロードしてテストするという風に変更したのだが、スレッド作って可能な限り同時に流した方が効率がいいよなぁと思い簡単なテストをしたらこけた。
っで調査。
問題になるのは、共有オブジェクト(DLL、so)で作られたライブラリを読み込むテスト。(意外な依存関係があったりするので、ピュアスキームだけマルチでって分けにはいかないのが辛い)。
なぜかその類のライブラリがあるとインポートエラーになる。ちょっと実装を覗いた。共有オブジェクトは一度呼ばれるとその情報が保存されて、同じオブジェクトを2度読み込まないようになっている。まぁこれはいい。っで、その中に初期化関数があるのだが、読み込みの際にそいつも一緒に呼ばれる。そうするとオブジェクトは初期化されたというフラグが立つ。ここに問題があった。
親スレッドが呼ぶ分にはまったく問題ないんだけど、複数の子スレッドで同一のDLLが呼ばれると問題になる。
この辺は多少以上に設計方針に関わっていて、子スレッドでインポートされたライブラリは親スレッドに影響を与えないという作りにしてあるのだが、これが拙い。兄弟間ではライブラリの共有が出来ないからだ。そうすると一度呼ばれたライブラリは2度と初期かされないので、兄が呼ぶと、弟が呼んでも答えてくれない。
解決策はまぁ、2つだろう。子供は親に迷惑をかけるものだと割り切るか、ターゲットを八方美人にするか。設計方針的には後者になるか。ただ、実際2度初期化をするとおかしくなるものもあるので、そこは気をつけないとまずいか。
っで調査。
問題になるのは、共有オブジェクト(DLL、so)で作られたライブラリを読み込むテスト。(意外な依存関係があったりするので、ピュアスキームだけマルチでって分けにはいかないのが辛い)。
なぜかその類のライブラリがあるとインポートエラーになる。ちょっと実装を覗いた。共有オブジェクトは一度呼ばれるとその情報が保存されて、同じオブジェクトを2度読み込まないようになっている。まぁこれはいい。っで、その中に初期化関数があるのだが、読み込みの際にそいつも一緒に呼ばれる。そうするとオブジェクトは初期化されたというフラグが立つ。ここに問題があった。
親スレッドが呼ぶ分にはまったく問題ないんだけど、複数の子スレッドで同一のDLLが呼ばれると問題になる。
この辺は多少以上に設計方針に関わっていて、子スレッドでインポートされたライブラリは親スレッドに影響を与えないという作りにしてあるのだが、これが拙い。兄弟間ではライブラリの共有が出来ないからだ。そうすると一度呼ばれたライブラリは2度と初期かされないので、兄が呼ぶと、弟が呼んでも答えてくれない。
解決策はまぁ、2つだろう。子供は親に迷惑をかけるものだと割り切るか、ターゲットを八方美人にするか。設計方針的には後者になるか。ただ、実際2度初期化をするとおかしくなるものもあるので、そこは気をつけないとまずいか。
2012-03-21
Weak hashtable
マクロ周りの修正と、デバッグ情報(主にファイル周りの情報)を何とかしようとしたらメモリがあっという間に飛ぶようになったので、ちょっとまじめに実装しようとしてみた。
問題になったのは、VM側にソースの情報を持たせているのだが、こいつが普通のハッシュテーブルなので要素は増えるけど減らないというのがある。たとえばユニットテストなんか走らせると最低でも500MBぐらい必要だった。
元もと使ってはいなかったがWeakハッシュテーブル自体はコードにあって(Gaucheからのパクリ)、単にこれを使えばいいかなぁと思っていたのだがそう単純な話でもなかった。
何が問題だったか。
GaucheのWeakハッシュテーブルはキー、値、もしくは両方という感じでどの要素がWeakポインタなのか指定できる。しかし、そのままの状態でうまく動いたのは値を指定した場合のみで、キーまたは両方を指定すると値が取り出せないか最悪クラッシュする。(最新版のソースは知らない+Gauche上で使ったことないのでその辺は考慮されているのかもしれない)
どうしてそれが起きたのか。
Weakハッシュテーブルに要素を入れるとき、GCが辿らないように要素を一段ラップするようになっている。問題はここで、値だけなら問題ないが、キーをラップしたときラップされたポインタは闇に消えていた。なので、値を取り出そうとすると必ず失敗する。(だって、キー自体とラッパーは違うんだもん)
ではどうしたか。
非常に醜い方法でとりあえず回避。ハッシュテーブル自体にラップされたキーの情報を持たせるようにした。値を入れる際にキーの情報も一緒に保存しておく。っで、取り出す際には保存先から生のキーを元にラップされたキーを取り出す。ただ、これ自体がGCから辿れると結局回収されないので、これ自体もWeakベクタで実装。ただ、キーの情報が増えるとベクタが爆発的に増えるのでパフォーマンスに影響がでる。(というか出てる)。
最終的にはメモリ使用量が最大で200MBくらいに落ち着いたので、まぁよしとしている(これ以外にもいろいろやっているが)。キャッシュされてしまえばソース情報は消えるわけで、コンパイルもスキップされるから速度的には問題なくなると思うし。
問題になったのは、VM側にソースの情報を持たせているのだが、こいつが普通のハッシュテーブルなので要素は増えるけど減らないというのがある。たとえばユニットテストなんか走らせると最低でも500MBぐらい必要だった。
元もと使ってはいなかったがWeakハッシュテーブル自体はコードにあって(Gaucheからのパクリ)、単にこれを使えばいいかなぁと思っていたのだがそう単純な話でもなかった。
何が問題だったか。
GaucheのWeakハッシュテーブルはキー、値、もしくは両方という感じでどの要素がWeakポインタなのか指定できる。しかし、そのままの状態でうまく動いたのは値を指定した場合のみで、キーまたは両方を指定すると値が取り出せないか最悪クラッシュする。(最新版のソースは知らない+Gauche上で使ったことないのでその辺は考慮されているのかもしれない)
どうしてそれが起きたのか。
Weakハッシュテーブルに要素を入れるとき、GCが辿らないように要素を一段ラップするようになっている。問題はここで、値だけなら問題ないが、キーをラップしたときラップされたポインタは闇に消えていた。なので、値を取り出そうとすると必ず失敗する。(だって、キー自体とラッパーは違うんだもん)
ではどうしたか。
非常に醜い方法でとりあえず回避。ハッシュテーブル自体にラップされたキーの情報を持たせるようにした。値を入れる際にキーの情報も一緒に保存しておく。っで、取り出す際には保存先から生のキーを元にラップされたキーを取り出す。ただ、これ自体がGCから辿れると結局回収されないので、これ自体もWeakベクタで実装。ただ、キーの情報が増えるとベクタが爆発的に増えるのでパフォーマンスに影響がでる。(というか出てる)。
最終的にはメモリ使用量が最大で200MBくらいに落ち着いたので、まぁよしとしている(これ以外にもいろいろやっているが)。キャッシュされてしまえばソース情報は消えるわけで、コンパイルもスキップされるから速度的には問題なくなると思うし。
2012-03-19
なんとなく
自分のブログの過去ログを眺めていた。2006年からこのブログ書いてるんだとちょっと感心。
最初の頃はPerl、C++にくびったけだったのが分かる。あと文章が幼いw(今も幼いが・・・)
FTPの実装方法が分からないなんていってる自分がいるのを見ると、技術的なスキルや知識はついたんだなぁと思う。(まぁ、Socket周りなんて仕事ではなくSagittariusの開発からだけど)
2009年からはこっちにいるのだが、その頃辺りからSICPとかSchemeの話題が出てくる。でもその前から言語の処理系を作りたいみたいな文章があって、その辺は変わってなんだなぁと実感。
結構いろんな箇所で自分は感情が欠落しているというのを誇張しているが、まぁ軽い厨二病をこじらせていたのだろう。まぁ、今では立派な甲斐性なしにレベルアップしたけど。
短い文が多いのは当時はブログに何を書いてもいいだろうと思っていたんだろう、どうせ人は見ないしと考えて。(今でも需要があるとは思わないが)。
読んでもその当時自分が何をしていたのかってのがいまいち思い出せない。けど、いろんな意味で自分は変わったんだなぁと実感した。本質は変わってないんだけど、枝葉というか、まだ若くて何も知らなかった自分(25、6なのに)というのから、人の目を気にして、評価を気にして、大切なものが何なのか分からなくなった自分という感じではあるが。(じゃあ、僕の本質って?多分あほなんでしょう。または考えなしか)
自分がしたことに後悔がないと言えば嘘になるし、可能であれば取り返したいという気持ちもあるけど、後ろを見てもしょうがないよねというのが一番強いではある。覆水盆に返らず、僕だけが水を溢したわけではないと思うけど、一度失ったものは帰ってこない。この国で独りで生きるのはまぁ辛いだろうが、なんとかなるだろう。 退かぬ、媚びぬ、省みぬ!(だっけ?)
最初の頃はPerl、C++にくびったけだったのが分かる。あと文章が幼いw(今も幼いが・・・)
FTPの実装方法が分からないなんていってる自分がいるのを見ると、技術的なスキルや知識はついたんだなぁと思う。(まぁ、Socket周りなんて仕事ではなくSagittariusの開発からだけど)
2009年からはこっちにいるのだが、その頃辺りからSICPとかSchemeの話題が出てくる。でもその前から言語の処理系を作りたいみたいな文章があって、その辺は変わってなんだなぁと実感。
結構いろんな箇所で自分は感情が欠落しているというのを誇張しているが、まぁ軽い厨二病をこじらせていたのだろう。まぁ、今では立派な甲斐性なしにレベルアップしたけど。
短い文が多いのは当時はブログに何を書いてもいいだろうと思っていたんだろう、どうせ人は見ないしと考えて。(今でも需要があるとは思わないが)。
読んでもその当時自分が何をしていたのかってのがいまいち思い出せない。けど、いろんな意味で自分は変わったんだなぁと実感した。本質は変わってないんだけど、枝葉というか、まだ若くて何も知らなかった自分(25、6なのに)というのから、人の目を気にして、評価を気にして、大切なものが何なのか分からなくなった自分という感じではあるが。(じゃあ、僕の本質って?多分あほなんでしょう。または考えなしか)
自分がしたことに後悔がないと言えば嘘になるし、可能であれば取り返したいという気持ちもあるけど、後ろを見てもしょうがないよねというのが一番強いではある。覆水盆に返らず、僕だけが水を溢したわけではないと思うけど、一度失ったものは帰ってこない。この国で独りで生きるのはまぁ辛いだろうが、なんとかなるだろう。 退かぬ、媚びぬ、省みぬ!(だっけ?)
promiseとfuture
C++11から入った機能。JavaのFutureとよく似てる?
まぁ、C++で使うことはないのでSagittariusですごくナイーブに実装してみた。ひょっとしたら使うようになるかもしれないというだけで。
まぁ、C++で使うことはないのでSagittariusですごくナイーブに実装してみた。ひょっとしたら使うようになるかもしれないというだけで。
(import (rnrs) (srfi :18) (clos user))
(define-class <promise> ()
((future :init-keyword :future)
(thread :init-keyword :thread :accessor promise-thread)))
(define-class <future> ()
((promise :accessor future-promise)))
(define (make-promise proc . args)
(let* ((thunk (lambda () (apply proc args)))
(thread (make-thread thunk))
(future (make <future> :thunk thunk))
(promise (make <promise> :future future :thread thread)))
(future-promise future promise)
(thread-start! thread)
promise))
(define-method get-future ((p <promise>))
(slot-ref p 'future))
(define-method get ((f <future>))
(let ((promise (future-promise f)))
(thread-join! (promise-thread promise))))
(let* ((promise (make-promise (lambda args
(thread-sleep! 1000) ;; heavy routine
(apply + args)) 1 2 3 4))
(future (get-future promise)))
;; do something
(print 'here)
;; wait
(print "get value " (get future)))
こんな感じ?あんまり何も考えてない。値の取得が2回起きたらどうなるとか。なんかこの程度だとスレッドの薄いラッパーにしか見えないなぁ。どうするのが正しいんだ?
2012-03-18
WATCOMとGCCの違いメモ
結構違いがあってびびった。まだコンパイルが通るだけでまだまともに動かないが・・・
あと、WATCOMのターゲットはWindowsなので、UNIX関連はまた別になるけど
最後のが特定できてないのでR6RSのテストケースが通らない。通した。modfのNaN問題だった。
また、動的モジュールのロードがおかしいのか分からないけど、拡張モジュールがまったくテストできない。
あまりメジャーな処理系ではないらしく、資料もそんなにないし、マニュアルでは痒いところに手が届かない(8バイト境界とか)。2日で何とかなるとは思っていなかったが、想像以上に癖がありすぎて挫折しそう。
とりあえずブランチ切ってコミット。他の処理系で問題なく動くならマージしようかな。とりあえず入れておけば誰か(一人プロジェクトなのに?)が突っ込みいれてくれるかもしれない。
あと、WATCOMのターゲットはWindowsなので、UNIX関連はまた別になるけど
- voidの関数が値を返すようなreturnをするとコンパイルエラー
- これはGCCやMSVCが甘すぎるのだと思う。正直こうあってほしい。
- small、medium、large、hugeがマクロとして定義されてる
- Linux版GCCのgetcとかputcのマクロ並に邪悪です。速攻undef。
- 構造体の初期化で使えるのは定数のみ
- 結構使っている箇所があった。正直許せよこれくらいと思った。
- NaNが0より大きい
- これははまった。数字じゃないのに、そんなの返すなよ。多分コンパイラのバグ(と思う)。
- 左シフトで桁あふれすると0になる
- Cの規格では未定義動作なのでコンパイラの警告を無視していた僕が悪いのだが。
- 静的領域や大域変数は4バイト境界に配置
- 8バイトを期待したコードを書いていると困る。doubleを噛ませても問答無用だった。__farキーワードで回避
- exp、log、powが微妙
- まだ原因を特定してないけど、上記の数学関数がOverflowやらRange errorやらDomain errorを投げる。GCCとMSVCは投げない。多分シフトの桁あふれと関連してるのだろう。中身があんまり賢くないようだ。
- externされている大域変数の参照が不正
- __farキーワードのせいなのか、LoadLibraryの問題なのかは分からない。後者はWin32 APIだからちょっと考え難いか。前者かな?リンカーという線もあるが。
- modfにINFINITYを渡すとNaNを返す
- GCCとMSVCは0を返す。
- 根本的にNaNの扱いがおかしい
- NAN==0.0が真になるとかありえないだろう。他にもいろいろ偽を返すべきところで真を返す。
- logに-INFINITYを渡すとDomain error
- だけならいいんだけど、そのまま-inf.0を返しやがる。+nan.0を期待しているのだが・・・
- エクスポートされる関数の名前がおかしい
- 普通は_nameなんだけど、name_と逆になる。dllexportがおかしい?。__cdeclをつける必要あり。
また、動的モジュールのロードがおかしいのか分からないけど、拡張モジュールがまったくテストできない。
あまりメジャーな処理系ではないらしく、資料もそんなにないし、マニュアルでは痒いところに手が届かない(8バイト境界とか)。2日で何とかなるとは思っていなかったが、想像以上に癖がありすぎて挫折しそう。
とりあえずブランチ切ってコミット。他の処理系で問題なく動くならマージしようかな。とりあえず入れておけば誰か(一人プロジェクトなのに?)が突っ込みいれてくれるかもしれない。
2012-03-17
Watcomにはまる
自宅のThinkPad X60+Cygwinの環境にちょっと疲れてきたので(遅い、不安定等)、Windows上で使える第3の選択肢としてWatcomでビルドできないか試行錯誤中。っで、ちょっとした問題が発生した。
VC、GCCともにメモリのアライメントが8ビット(バイト?)境界なんだけど、Watcomは4ビットだった。これ実は大問題で、いろいろ8ビット境界を想定して書いているので思わぬところでこける。
オプションで指定できるのは構造体のアライメントだけっぽいし、staticな値を8ビット境界に置くにはどうしたらいいんだろう?ダメなら諦めるしかないが・・・
VC、GCCともにメモリのアライメントが8ビット(バイト?)境界なんだけど、Watcomは4ビットだった。これ実は大問題で、いろいろ8ビット境界を想定して書いているので思わぬところでこける。
オプションで指定できるのは構造体のアライメントだけっぽいし、staticな値を8ビット境界に置くにはどうしたらいいんだろう?ダメなら諦めるしかないが・・・
2012-03-16
クロージャー?
Twitterで呟いたが、Javaの無名クラスは厳密にはクロージャーになりえず、JDK8辺りで入る予定のlambdaも無名クラスの糖衣構文になるとかという話を昨日バーで同僚としていた。
糖衣構文でもあれば便利だろうなぁと思う場面が山ほどあるので、是非早いとこ実装してもらいたいが(JDK7では見送られた)。
話に参加していたもう一人の同僚が、違いが分からないと言っていたので、関数型言語のクロージャーとどう違うのかというのでも書いてみようかなぁと。ただ、僕自身あんまり理解してないので間違いは山ほどあるかと・・・
そもそも、クロージャーとは何ぞやと。詳しい説明はWikipediaでも見てもらうとして、上記で議論になっていたのは捕捉時の環境が閉じているかどうかということであった。JavaやC++ではここが完全に閉じることができず、渡された自由変数が参照渡しになる。以下はJavaでそれっぽく見せるようにしたコード。(C++では補足さえ出来ない)
ではわれらがSchemeではどうだろうか?
これが出来て何が嬉しいかと言われると正直微妙ではある。(結構使うけどこういうの)
ただ、Javaでもfinalつければ捕捉出来るんだし、ほぼ同じじゃないのだろうか?(いい加減)
糖衣構文でもあれば便利だろうなぁと思う場面が山ほどあるので、是非早いとこ実装してもらいたいが(JDK7では見送られた)。
話に参加していたもう一人の同僚が、違いが分からないと言っていたので、関数型言語のクロージャーとどう違うのかというのでも書いてみようかなぁと。ただ、僕自身あんまり理解してないので間違いは山ほどあるかと・・・
そもそも、クロージャーとは何ぞやと。詳しい説明はWikipediaでも見てもらうとして、上記で議論になっていたのは捕捉時の環境が閉じているかどうかということであった。JavaやC++ではここが完全に閉じることができず、渡された自由変数が参照渡しになる。以下はJavaでそれっぽく見せるようにしたコード。(C++では補足さえ出来ない)
package closure;
public interface Lambda<T> {
T apply(Object... args);
}
// 別ファイル
package closure;
public class Closure {
private Object obj;
public void run() {
// property
Lambda<Object> lam = new Lambda<Object>() {
@Override
public Object apply(Object... args) {
obj = args[0];
System.out.println(obj);
return obj;
}
};
final Object obj2 = (Object)"string";
Lambda<Object> lam2 = new Lambda<Object>() {
@Override
public Object apply(Object... args) {
// obj2 = args[0]; // *1 compile error
System.out.println(obj2);
return null;
}
};
System.out.println(lam.apply("here we go"));
System.out.println(obj);
lam2.apply();
}
public static void main(String[] args) {
Closure cl = new Closure();
cl.run();
}
}
*1の部分が重要で、Javaでは無名クラスの中から参照できる自由変数(とここでは呼ぶ)は変更不可能でなければならない。多分JVMの実装上も問題だろう。lam2がrunから戻った際にスタックからobj2が消えるのでその辺が問題になると思われる。ではわれらがSchemeではどうだろうか?
(define obj #f)
(define (runner lam1 lam2)
(print (lam1 "here we go"))
(print (lam2 "we can do it")))
(define (main args)
(let* ((obj2 "string")
(lam1 (lambda (o) (set! obj o) o))
(lam2 (lambda (o) (set! obj2 o) o)))
(runner lam1 lam2)
(print obj #\: obj2)))
#|
here we go
we can do it
here we go:we can do it
|#
あまりいい例ではない気もするが、lam2で捕捉されたobj2の値が変更されるとlambdaの外側のでも問題なく変更されている。これが出来て何が嬉しいかと言われると正直微妙ではある。(結構使うけどこういうの)
ただ、Javaでもfinalつければ捕捉出来るんだし、ほぼ同じじゃないのだろうか?(いい加減)
(define obj #f)
(define (runner o run?)
(let* ((obj2 o)
(lam1 (lambda (o) (set! obj o) o))
(lam2 (lambda (o) (set! obj2 o) o)))
(cond (run?
(print (lam1 "here we go"))
(print (lam2 "we can do it"))
(print obj #\: obj2))
(else
(values lam1 lam2 obj2)))))
(define (main args)
(let ((o "string"))
(runner o #t)
(receive (lam1 lam2 obj2) (runner o #f)
(print (lam1 "here we go"))
(print (lam2 "we can do it"))
(print obj #\: obj2))
(print o)))
#|
here we go
we can do it
here we go:we can do it
here we go
we can do it
here we go:string
string
|#
こっちの方が捕捉時の環境というのが捕らえやすいだろうか?あんまり変わらないか?
2012-03-13
British or American English?
カナダにいたときに購読し始めたニュースレター(今はほとんど読んでなかった)から届いた面白げなタイトル。
その中にあった動画の一つがこれ
簡単な英語と米語の語彙の違いを紹介している。違いは以下のような感じ
視ると面白い。MeanがずっとBritishの方しか知らなかったり(Being Nastyなんて知らなんだ)。意外と米語だと思っていたのが実は英語だったとか(GardenとYardとか。スコットランドヤードって言うやん!)
自分の語彙を見ると主に日本で習う英語は米語だと思うが、たまに変なのもある(Trousersとか、学校ではこれがズボンと習ったなぁ。でも下着はUnderwearだった気がする)
謳い文句には文法も書いてあったのにサイトにそれらしいものは特に無かった。残念。
その中にあった動画の一つがこれ
簡単な英語と米語の語彙の違いを紹介している。違いは以下のような感じ
| British | American |
|---|---|
| Trousers | Pants |
| Pants | Underwear |
自分の語彙を見ると主に日本で習う英語は米語だと思うが、たまに変なのもある(Trousersとか、学校ではこれがズボンと習ったなぁ。でも下着はUnderwearだった気がする)
謳い文句には文法も書いてあったのにサイトにそれらしいものは特に無かった。残念。
昨日の続き
意外とてこずっている。(まぁ、当たり前か・・・)
syntax-caseの実装が甘いのがここにきて痛い感じだ。
たとえばこんなコード。
syntax-rules内のxが3回目のxと同じため出力としてはinnerが帰ってくる。でも、printマクロを噛ませないとouterが帰る。これは最初のxが束縛された際の環境をマクロ展開器が知っているため、単なるシンボルであれば環境を閉じ込めて識別子にすることができるからだ。
あぁ、そうか。ならラップする際に何とかできればいいのか。いや、待てよ。同じ識別子なんだから、環境内でも同じか。結局簡単な方法はunrenameすることになるのか・・・
さて、もう一ひねりしてみるか・・・orz
syntax-caseの実装が甘いのがここにきて痛い感じだ。
たとえばこんなコード。
(define-syntax print
(syntax-rules ()
((_ o)
(begin (display o) (newline)))))
(print
(let ((x 'outer))
(let-syntax ((m (syntax-rules () ((m) x))))
(let ((x 'inner)) (m)))))
xという変数は合計で3回出現しているが、printマクロを噛ませることですべて同じ識別子へと見事な変貌を遂げている。これが問題なのだ・・・syntax-rules内のxが3回目のxと同じため出力としてはinnerが帰ってくる。でも、printマクロを噛ませないとouterが帰る。これは最初のxが束縛された際の環境をマクロ展開器が知っているため、単なるシンボルであれば環境を閉じ込めて識別子にすることができるからだ。
あぁ、そうか。ならラップする際に何とかできればいいのか。いや、待てよ。同じ識別子なんだから、環境内でも同じか。結局簡単な方法はunrenameすることになるのか・・・
さて、もう一ひねりしてみるか・・・orz
2012-03-12
マクロとコンパイラと不具合と
ずいぶん昔から以下のようなマクロが動かない。
そもそも、これは何か?
これはsyntax-caseのR6RSテストスイートをパスさせるために入れた苦肉の策である。
具体的には、syntax-caseを通った式はすべて識別子に変換される。その際に、識別子の同一性を保つため同一のsymbolであれば同一の識別子になるようにしている。
何故これは起きるのか?
上記のままでは拙い場合があった。問題としては一度識別子に変換されると2度目の変換ルーチン(以下renameと呼ぶ)ではそのままその識別子返してくる。その際に、ローカルに束縛された識別子が問題になった(と思う)。だが、マクロの展開器は賢くないのでコンパイラ側でローカルに束縛された識別子をシンボルに直してやる必要があった。また、その際に単に構文情報を剥ぎ取るだけではだめで、シンボルに直された識別子が一意である必要があった。
上記の例では(define-lambda ...)の中で「t」というシンボルはすべて同一の識別子に変換される。普通にquoteされるなら構文情報を剥ぎ取るだけなので問題ないが、quasiquoteまではunrename(と呼んでいる)ルーチンは見ない。そのため、quasiquote内の最初の「t」はunrenameされた状態で出力される。
どう解決するか?
解決方法は2つあると考えていて、unrenameがquasiquoteを見る。もしくは、unrenameをやめる。
前者は正直これ以上糞コードを増やしたくないので却下。後者はなぜunrenameなどと言うものが必要だったかという経緯を考えれば問題ない気がする。
つまり、renameルーチンが識別子を受け取った際に、その識別子をコピーしてやればいいはず。そうすれば、識別子が同一過ぎて困るという問題は無いはずだ。具体的にはwrap-syntaxという処理が式を識別子に変換しているのでそれをちょっといじって、コンパイラからunrename関係の処理をごっそり削ればいけるはず。
とりあえず試してみる。
(define-syntax define-lambda
(syntax-rules ()
((_ name formals body ...)
(define name (lambda formals body ...)))))
(define-lambda test (t rest) `(t ,t))
(test 'a 'b) ;; => (t.xxxxxx a) xxxxxxは適当な16進数
なぜか?実は原因も全部分かっているのだが、直すに当たって余計な不具合を入れないためにもこれが必要だった経緯を書いておく。そもそも、これは何か?
これはsyntax-caseのR6RSテストスイートをパスさせるために入れた苦肉の策である。
具体的には、syntax-caseを通った式はすべて識別子に変換される。その際に、識別子の同一性を保つため同一のsymbolであれば同一の識別子になるようにしている。
何故これは起きるのか?
上記のままでは拙い場合があった。問題としては一度識別子に変換されると2度目の変換ルーチン(以下renameと呼ぶ)ではそのままその識別子返してくる。その際に、ローカルに束縛された識別子が問題になった(と思う)。だが、マクロの展開器は賢くないのでコンパイラ側でローカルに束縛された識別子をシンボルに直してやる必要があった。また、その際に単に構文情報を剥ぎ取るだけではだめで、シンボルに直された識別子が一意である必要があった。
上記の例では(define-lambda ...)の中で「t」というシンボルはすべて同一の識別子に変換される。普通にquoteされるなら構文情報を剥ぎ取るだけなので問題ないが、quasiquoteまではunrename(と呼んでいる)ルーチンは見ない。そのため、quasiquote内の最初の「t」はunrenameされた状態で出力される。
どう解決するか?
解決方法は2つあると考えていて、unrenameがquasiquoteを見る。もしくは、unrenameをやめる。
前者は正直これ以上糞コードを増やしたくないので却下。後者はなぜunrenameなどと言うものが必要だったかという経緯を考えれば問題ない気がする。
つまり、renameルーチンが識別子を受け取った際に、その識別子をコピーしてやればいいはず。そうすれば、識別子が同一過ぎて困るという問題は無いはずだ。具体的にはwrap-syntaxという処理が式を識別子に変換しているのでそれをちょっといじって、コンパイラからunrename関係の処理をごっそり削ればいけるはず。
とりあえず試してみる。
2012-03-08
開発環境
ほぼ月1でリリースしてると、月1でフルビルドしないといけないということになっていて、Cygwin+非力なマシンでは厳しいなぁと思えてきた。
もっと非力なマシン+Linux GCCだと速いという事はやはりCygwinが遅いんだろうなぁと思い、何か別な環境はないかと探してみる。
とりあえず基準というか絶対条件として、
っで、BCC32(フリー版の5.5)は僕が大学の時からバージョンアップしてないという記憶なのでさすがに10年以上前ではどうよ?と思いパス。(まぁ、こじゃれた最新機能はつかっていないのでOKな気もするが)となるとWatcomしかないじゃんと思い試してみた。
結論。BoehmGCすらコンパイルできなかった・・・orz
多分どこかCMakeLists.txtの記述がおかしいのだろうと思うのだが、Windows環境ではMSVC決め打ちの部分が多いので修正も大変。とりあえずwmakeが打てるところまできてこれが起きたので一気に気力が持っていかれた。
じゃあ素直にMSVCでいいじゃんと思うのだが、インストールに2G以上使うような富豪プログラムなのでHDDのスペースが足りない。(Cドライブが10Gしか切ってない上に、すでに8G使われている)
Windows SDKは問答無用で.NETがくっついてくるし、打つ手なし。
だれかいい案ないですか?
もっと非力なマシン+Linux GCCだと速いという事はやはりCygwinが遅いんだろうなぁと思い、何か別な環境はないかと探してみる。
とりあえず基準というか絶対条件として、
- CMakeがサポートしてるコンパイラ
っで、BCC32(フリー版の5.5)は僕が大学の時からバージョンアップしてないという記憶なのでさすがに10年以上前ではどうよ?と思いパス。(まぁ、こじゃれた最新機能はつかっていないのでOKな気もするが)となるとWatcomしかないじゃんと思い試してみた。
結論。BoehmGCすらコンパイルできなかった・・・orz
多分どこかCMakeLists.txtの記述がおかしいのだろうと思うのだが、Windows環境ではMSVC決め打ちの部分が多いので修正も大変。とりあえずwmakeが打てるところまできてこれが起きたので一気に気力が持っていかれた。
じゃあ素直にMSVCでいいじゃんと思うのだが、インストールに2G以上使うような富豪プログラムなのでHDDのスペースが足りない。(Cドライブが10Gしか切ってない上に、すでに8G使われている)
Windows SDKは問答無用で.NETがくっついてくるし、打つ手なし。
だれかいい案ないですか?
2012-03-07
DER, BER, CER?
ASN.1の代表的なエンコード(?)方式。
正直CERは見たことないのでよく知らないが、職業柄DERはよく見るしそれにくっついてBERもよく見る。
Sagittariusに(ようやく)ASN.1のバイナリを読むライブラリを入れたのでちょっといろいろ整理も兼ねて。
基本的な部分はBouncycastleの移植といった感じにしてあるので、クラスの継承関係もそんな感じ。
DERを読むならBERを読むのも簡単なので、DERを基本クラスにしてそのBERは派生。
Readerはタグみて読むだけなので、クラスの派生を知る必要はないが、両方読めるようにタグの種類でdispatchする感じ。
エンコードはおそらく本来はBERのオブジェクトも条件によってはDERを出力しないとまずいんだろうけど、面倒なのでBERだけ出力。つまり、BERを含む証明書(あるのか?)は読み込みしてDERだけに変換という荒業はできない。(これはそのうち何とかするかも。parameter使えば多分なんとかなる)
昔作ったASN.1のパーサーがあるけど、これどうしよう?一応バイナリと構文の整合性チェックに使う予定だったんだけど、やるのしんどい・・・
DERとBERの違いはなんぞやというGoogle検索の結果を勝手に予測して。
ここが詳しいけど、一応自分でも。
本質的には一緒。DERはタグ、長さ、データの順で書かれたバイナリ。タグは基本2種類あって、プリミティブと拡張(?訳語しらない)されたもの。最初の1バイトと0x1Fを論理積(and)した値が0x1Fなら続く数バイトはタグになる。
BERの方が機能的にはスーパーセットらしい(構築されたoctet stringとか?)。PKCS12形式の証明書群の中にあるのを見た。多分暗号化されたDERとか入れれるのだろう。(他のViewerで見るとどうもSagittariusのはうまく読めてないくさい。そのうち直そう)
正直CERは見たことないのでよく知らないが、職業柄DERはよく見るしそれにくっついてBERもよく見る。
Sagittariusに(ようやく)ASN.1のバイナリを読むライブラリを入れたのでちょっといろいろ整理も兼ねて。
基本的な部分はBouncycastleの移植といった感じにしてあるので、クラスの継承関係もそんな感じ。
DERを読むならBERを読むのも簡単なので、DERを基本クラスにしてそのBERは派生。
Readerはタグみて読むだけなので、クラスの派生を知る必要はないが、両方読めるようにタグの種類でdispatchする感じ。
エンコードはおそらく本来はBERのオブジェクトも条件によってはDERを出力しないとまずいんだろうけど、面倒なのでBERだけ出力。つまり、BERを含む証明書(あるのか?)は読み込みしてDERだけに変換という荒業はできない。(これはそのうち何とかするかも。parameter使えば多分なんとかなる)
昔作ったASN.1のパーサーがあるけど、これどうしよう?一応バイナリと構文の整合性チェックに使う予定だったんだけど、やるのしんどい・・・
DERとBERの違いはなんぞやというGoogle検索の結果を勝手に予測して。
ここが詳しいけど、一応自分でも。
本質的には一緒。DERはタグ、長さ、データの順で書かれたバイナリ。タグは基本2種類あって、プリミティブと拡張(?訳語しらない)されたもの。最初の1バイトと0x1Fを論理積(and)した値が0x1Fなら続く数バイトはタグになる。
BERの方が機能的にはスーパーセットらしい(構築されたoctet stringとか?)。PKCS12形式の証明書群の中にあるのを見た。多分暗号化されたDERとか入れれるのだろう。(他のViewerで見るとどうもSagittariusのはうまく読めてないくさい。そのうち直そう)
2012-03-02
Sagittarius version 0.3.0リリース
リリースノートを書くのが億劫というか、何を直して何を追加したか思い出せん。もっとまめにChangeLog書かないと・・・
Sagittarius Scheme 0.3.0がリリースされました。このバージョンからCLOSが組み込みでサポートされます。ただし、すべての機能がサポートされているわけではありません。使用するには(clos user)もしくは(clos core)ライブラリをインポートしてください。
修正された不具合
多分これ以上にいろいろいじったんだけど、思い出せない。
Sagittarius Scheme 0.3.0がリリースされました。このバージョンからCLOSが組み込みでサポートされます。ただし、すべての機能がサポートされているわけではありません。使用するには(clos user)もしくは(clos core)ライブラリをインポートしてください。
修正された不具合
- internal defineされた値がマクロ内から参照できない問題が修正されました。
- (clos user) 及び (clos core)が追加されました。CLOS風のプログラムを書くにはこのライブラリをインポートする必要があります。
- (text markdown)が追加されました。簡単なマークダウン形式のテキストのパース及びHTMLへの出力を行います。
- (scribble)が(scribble parser)、(scribble convert)及び(scribble plugin)に分割されました。
- (sagittarius document html)が追加されました。Sagittariusが作成するHTML形式のドキュメントを作成するのに使われています。
- (getopt)が追加されました。SRFI-37の薄いラッパーです。
- regex-replace-all 及び regex-replace-firstの第2引数がプロシージャを取れるようになりました。Javascriptの機能にinspireされたものです。詳しくはドキュメントを参照してください。
- binary-port?及びtextual-port?がR7RS互換になり、ポート以外の引数を受け取ってもエラーを投げなくなりました。
- get-bytevector-n及びget-bytevector-someのパフォーマンスが多少改善されました。内部的に2度メモリの割付を行っていたのが解消されています。
- (sagittarius process)の機能が大幅に改善されました。JavaのProcessクラスの設計思想に基づいて書き換えられています。
- (sagittarius threads)でしばしばデッドロックを起こす問題が解消されました。これによりドキュメントのサポートSRFIの欄に正式にSRFI-18が追加されています。ただしWindows上でthread-terminate!を使うと予期しない動作をします。現状確認されている不具合です。
- (sagittarius process)が正式にドキュメント化されました。
多分これ以上にいろいろいじったんだけど、思い出せない。
rebase問題+process
Sagittariusでプロセスの実装をしている際に、Cygwin上だとforkでころころ落ちてていらいらしていた。Cygwinのforkは不安定だという話は聞いていたので、こんなものだろうかと思っていたのだが、(実際、出てくるエラーメッセージもresource temporary not availableだったし)、いろいろ調べてみるとrebaseすると直るみたいな記事が山ほどあったので試してみた。
結果、あぁ、これだったのね、という感じで今はさくさく動いている。別段Cygwin上でプロセスを起動させることはないのだが、(これ自体Windowsのバッチでmavenのビルドスクリプトを書くのが苦痛で作ったものなので^^;)、動くとなるとなんらかに使えるかなぁとか考えてしまう。
と、これだけだと微妙なので、新生プロセスライブラリの概要でも。(誰も見てない?)
低レベルAPIのシグネチャ(これって日本語でなんていうの?)は特に変更なし。ラッパーで作っていたrunプロシージャが(name args)から(name . args)になって、書くのが多少楽になった。
今までは問答無用で標準入出力にリダイレクトしていたけど、パイプを通してSchemeからそれらの出力結果を取得できるようにした。(低レベルAPI)
実装上どうしようもなかったのだが、POSIX環境とWindows環境で微妙な差がある。POSIXだとプロセスの使い回しができるのに対し(PIDは一緒だが)、Windowsだとできない。これは、Scheme上では見えないけど、プロセスオブジェクトを作った際に実際にWindowsではプロセスを作ってしまうが、POSIXは後からforkとexecで実行するための情報を格納しているだけという違い。
設計思想的には両方ともWindows風にしてしまいたいが、僕の頭では無理。
理由:
結果、あぁ、これだったのね、という感じで今はさくさく動いている。別段Cygwin上でプロセスを起動させることはないのだが、(これ自体Windowsのバッチでmavenのビルドスクリプトを書くのが苦痛で作ったものなので^^;)、動くとなるとなんらかに使えるかなぁとか考えてしまう。
と、これだけだと微妙なので、新生プロセスライブラリの概要でも。(誰も見てない?)
低レベルAPIのシグネチャ(これって日本語でなんていうの?)は特に変更なし。ラッパーで作っていたrunプロシージャが(name args)から(name . args)になって、書くのが多少楽になった。
今までは問答無用で標準入出力にリダイレクトしていたけど、パイプを通してSchemeからそれらの出力結果を取得できるようにした。(低レベルAPI)
実装上どうしようもなかったのだが、POSIX環境とWindows環境で微妙な差がある。POSIXだとプロセスの使い回しができるのに対し(PIDは一緒だが)、Windowsだとできない。これは、Scheme上では見えないけど、プロセスオブジェクトを作った際に実際にWindowsではプロセスを作ってしまうが、POSIXは後からforkとexecで実行するための情報を格納しているだけという違い。
設計思想的には両方ともWindows風にしてしまいたいが、僕の頭では無理。
理由:
プロセスオブジェクトを作成した段階でそれぞれのリダイレクト先にアクセスできるようにしたかった。でないと走らせる前に入出力のリダイレクト先を読み取るとか書き込むということができないから。また、作成と同時にプロセスが走るようにするとオブジェクトを作った意味が薄れるため。誰かいい解決方法教えて。
2012-03-01
Win32プロセス
プロセスの実装を何とかしようとしているのだが、調べても答えが出てこない問題がでた。
現状、プロセスを作成した際に標準入力、出力、エラーを名前なしパイプに割り当てている。っで、プロセスは非同期もしくは同期(単に終了まで待つだけ)で起動できるのだが、MSDNを読むと作成されたパイプはバッファーの上限があるらしく、上限に達した場合読み取ってやらないと書き込みができなくなるという。
あんまりログを吐かないプロセスなら問題ないが、mavenでがりがりログを吐く上にコンパイルされるプロジェクトが20以上あるとなるとバッファーの上限はあっという間に超える。
じゃあ、読み取ってやればいいじゃんという話になるのだが、パイプから何かを読み取ろうとした際にまだ何も書き込まれていない状態だと現状EOFを返すのでループで回してもすぐ終了してしまう。っで多分デッドロックというかバッファーがいい感じに満杯になってうんともすんとも言わなくなる。
こういう場合って多くの処理系はどうやって対応しているのだろうか?
とりあえず、読み込みの方をいじった方がいいだろうか?
現状、プロセスを作成した際に標準入力、出力、エラーを名前なしパイプに割り当てている。っで、プロセスは非同期もしくは同期(単に終了まで待つだけ)で起動できるのだが、MSDNを読むと作成されたパイプはバッファーの上限があるらしく、上限に達した場合読み取ってやらないと書き込みができなくなるという。
あんまりログを吐かないプロセスなら問題ないが、mavenでがりがりログを吐く上にコンパイルされるプロジェクトが20以上あるとなるとバッファーの上限はあっという間に超える。
じゃあ、読み取ってやればいいじゃんという話になるのだが、パイプから何かを読み取ろうとした際にまだ何も書き込まれていない状態だと現状EOFを返すのでループで回してもすぐ終了してしまう。っで多分デッドロックというかバッファーがいい感じに満杯になってうんともすんとも言わなくなる。
こういう場合って多くの処理系はどうやって対応しているのだろうか?
とりあえず、読み込みの方をいじった方がいいだろうか?
2012-02-29
うるう年
すっかり忘れていた。折角なので何か書いておこうというだけの話。
ここ数日(といっても今日で2日目だが)風邪ひいていて結構体がだるい。というか基本起き上がるとくらくらするのでベッドの中でごろごろしている。
早く治らないかなぁ。まぁ、でも明日は仕事にいくだろうけど。
ここ数日(といっても今日で2日目だが)風邪ひいていて結構体がだるい。というか基本起き上がるとくらくらするのでベッドの中でごろごろしている。
早く治らないかなぁ。まぁ、でも明日は仕事にいくだろうけど。
2012-02-26
親の心子知らず
母親とは子供のことでいろいろ何か出来ないか模索せずにはいられない生き物なのだろうとちょっと実体験した話。
いろいろあって関係が壊滅的になっていた(今はほんの少し持ち直したと思う)のが事の始まり。昨日いきなり話し合いの場を設けられた。何故こうなったのかというのが主なもの。こういう話で原因がはっきりしていることってあるのかは知らないが、もし原因があるなら僕だろう。単にいろいろ覚悟が足りなかったという話だ。あんまり優秀な捕手ではないので、飛んでくる球を全部受けきれずという感じだ。(まぁ、直球すら落球していたという話ではあるのだが)
っで、一夜明けて今日、いきなりアントワープに行こうという提案が飛んできた。あぁ、いろいろ考えた結果「2人で何かをする」というのがそこだったんだろうなぁと瞬時に理解。でも、日曜のアントワープなんてただ歩くだけだし、疲れも溜まっていたのでお断りをした。んで、次がどうやらアムステルダムで買い物だったみたい。
正直どういった経緯でアントワープからアムステルダムになったのかは知らないけど、電話があって僕は行かないということを知った際の反応からこれもその一つだったんだなぁと理解。いろいろ申し訳ないなぁとは思いつつ、でも僕買い物に付き合わされても正直ストレスにしかならないんだよなぁとかも思ったり。
いろいろ好意を無にしてるなぁとは思うし、迷惑かけてるなぁとは思うけどう~ん。
甲斐性無しのダメ男ですいません。
(上記は既に謝ってるので、ネット上で言うなよというのはなしの方向で。ブログに書いてるのは単なるはけ口です。こういうとき日本語が分かる友人がオランダでほしいなぁと思う。)
いろいろあって関係が壊滅的になっていた(今はほんの少し持ち直したと思う)のが事の始まり。昨日いきなり話し合いの場を設けられた。何故こうなったのかというのが主なもの。こういう話で原因がはっきりしていることってあるのかは知らないが、もし原因があるなら僕だろう。単にいろいろ覚悟が足りなかったという話だ。あんまり優秀な捕手ではないので、飛んでくる球を全部受けきれずという感じだ。(まぁ、直球すら落球していたという話ではあるのだが)
っで、一夜明けて今日、いきなりアントワープに行こうという提案が飛んできた。あぁ、いろいろ考えた結果「2人で何かをする」というのがそこだったんだろうなぁと瞬時に理解。でも、日曜のアントワープなんてただ歩くだけだし、疲れも溜まっていたのでお断りをした。んで、次がどうやらアムステルダムで買い物だったみたい。
正直どういった経緯でアントワープからアムステルダムになったのかは知らないけど、電話があって僕は行かないということを知った際の反応からこれもその一つだったんだなぁと理解。いろいろ申し訳ないなぁとは思いつつ、でも僕買い物に付き合わされても正直ストレスにしかならないんだよなぁとかも思ったり。
いろいろ好意を無にしてるなぁとは思うし、迷惑かけてるなぁとは思うけどう~ん。
甲斐性無しのダメ男ですいません。
(上記は既に謝ってるので、ネット上で言うなよというのはなしの方向で。ブログに書いてるのは単なるはけ口です。こういうとき日本語が分かる友人がオランダでほしいなぁと思う。)
2012-02-25
プロセスをちょっと本格的に実装
以前からとりあえず動く、というか単に他プロセスが呼べるレベル、のものはあったのだがさすがにこのままではなぁと思いちょっと改良(改悪?)してみた。
もともと設計の方針としてはJavaのProcessクラスみたいな感じで入力、出力、エラー出力のポートをプロセスが持っていてそれらをいじれるようにしようとしていた。っが、とりあえず全部標準入出力にリダイレクトして適当にしていた。
っで、ちょっと思い立ってまじめにそれらを割り当てることにした。まぁ上手くいってる。っが、ここでちょっとした問題が。
元々この機能は仕事でmavenを叩くのにWindowsのバッチでは厳しいなぁと思っていたから作ったのだが、今回の変更で標準出力にリダイレクトされないのでログが見辛い。また、走っているプロセスのパイプに対して出力があったのか知る方法がないので、出力ポートからログを上手く取得できないという問題がでた。
解決方法はいまいちいい案がないのだが、とりあえず出力のリダイレクト先を指定できるようにするとか、char-ready?(ポートはバイナリなのでu8-ready?か)的な何かをまじめに実装するか、プロセスが終了するまでじっと待ってからログ吐く(運用回避?)のどれかだろうか?
Rubyのspawnとかどうしてるんだろう?(使ったこと無いけど、いろいろ出来そうだなぁとドキュメント見て思った)
もともと設計の方針としてはJavaのProcessクラスみたいな感じで入力、出力、エラー出力のポートをプロセスが持っていてそれらをいじれるようにしようとしていた。っが、とりあえず全部標準入出力にリダイレクトして適当にしていた。
っで、ちょっと思い立ってまじめにそれらを割り当てることにした。まぁ上手くいってる。っが、ここでちょっとした問題が。
元々この機能は仕事でmavenを叩くのにWindowsのバッチでは厳しいなぁと思っていたから作ったのだが、今回の変更で標準出力にリダイレクトされないのでログが見辛い。また、走っているプロセスのパイプに対して出力があったのか知る方法がないので、出力ポートからログを上手く取得できないという問題がでた。
解決方法はいまいちいい案がないのだが、とりあえず出力のリダイレクト先を指定できるようにするとか、char-ready?(ポートはバイナリなのでu8-ready?か)的な何かをまじめに実装するか、プロセスが終了するまでじっと待ってからログ吐く(運用回避?)のどれかだろうか?
Rubyのspawnとかどうしてるんだろう?(使ったこと無いけど、いろいろ出来そうだなぁとドキュメント見て思った)
2012-02-23
Boehm GC "too many heap sections" error
Well, the reason why I am writing this article is it's not because I found the solution for that but I have figured out which version I could avoid this. So this is just a memo.
Boehm GC is one of the coolest library for C developer however it still has a lot of problems to use all platform (I guess). When I got this error, I was using Cygwin to develop my own project Sagittarius and trying to run tests. The GC version was 7.2 alpha 6. I actually used version 7.1 before and the reason why I tried to use the latest version was to solve multi thread problem. Well, as you can see it was a wrong decision. Each time I tried to run the tests it failed. So I decided not to use it and revised to stable (they say) version.
If you google this error message, you can probably see the solution which you need to build it with LARGE_CONFIG ld flag. Unfortunately, I haven't tried it because I also saw a lot of article which said it did not solve any problem.
Sorry if you google this error message to solve your problem, I have just written this article for nothing actually:-p
2012-02-20
宗教と家族
またこれ系のネタだ。まぁ、たぶんこれで最後だろうが。
あなたには彼女(もしくは彼氏)がいます。っでその兄妹がオウム真理教の信者であなたの彼女(彼氏)に「この宗教はすごくいいんだ」と勧めています。そんなときあなたはどうしますか?
あなたには彼女(もしくは彼氏)がいます。っでその兄妹がオウム真理教の信者であなたの彼女(彼氏)に「この宗教はすごくいいんだ」と勧めています。そんなときあなたはどうしますか?
- 止める
- 放置する
- 自分も改宗する
2012-02-17
常識で考えましょう...
Togetterにあったまとめ
@May_Roma流英語習得法:「常識で考えましょう…」
おおむね賛成なんだけど、微妙だなぁと思ったのが1個。(実は最初の15個くらいしか見てないので他にもあるかもしれないが)
https://twitter.com/#!/May_Roma/status/168427967175860225
とりあえず「日本国内で勉強する」ということに絞るとすれば、当てはまるのかもしれないが、E○Cとかの英会話学校だと「高いけど先生はまともじゃない」なんてことがままある。実際僕も日本で英会話学校にいっていたのだが、あまりたいした成果はなかったような気がする。もちろん0ではないし、その後カナダに行った際に役に立ってはいたので無駄ではなかったとは思うが。この場合はおそらくここで言う「まともな先生」というのがキーワードなんだろう。それを探すのにスキルがいるということだ。
個人的に上記はとりあえず僕が思ったものでも小さいもので、大きくそれは違うだろうと思ったのは、この文章から見て取れた「金を払わないと英語は習得できない」というもの。(国語の点数は低い方だったのでそんなこと言ってないと言われると以下は破綻します)。
僕がある程度(ビジネスでも使える程度)英語が喋れるようになったのは高い金を払って先生から授業を受けたからではない。どちらかといえばそのような環境にいるからだと思っている。つまり英語で仕事をする環境にいるということ。同じことが日本で働いていた時にも言えて、大学を卒業してから身につけた日本語というものが非常にたくさんある。(御社とか弊社とか学生時代は知らんかった)
「習うより慣れろ」という言葉があるように実際に使われている言葉に触れるというのは何者にも代え難い勉強方法ではないだろうか。ただこれを言うと、
勉強なら他所でやれ
実際、僕もここで働き始めて英語の勉強をせざるを得なかった。具体的には電話の応対とかね。そうはいってもそれに対して金は払ってない(ネット代は含まない)。
効率という点を除けば手段はいくらでもあるはずだ。
「まともな先生」というのが人間以外も指すなら、高い金を除いて賛成ではあるが。
@May_Roma流英語習得法:「常識で考えましょう…」
おおむね賛成なんだけど、微妙だなぁと思ったのが1個。(実は最初の15個くらいしか見てないので他にもあるかもしれないが)
https://twitter.com/#!/May_Roma/status/168427967175860225
日本語力つけたい外人が、日本語でちゃんと喋ったり書いたりできないDQNに日本語習ってもうまくなるわけないでしょう。英語も同じでまともな先生に高い金を払って習わないとうまくなるわけないです。高い先生は自分の勉強に投資してんですよ。常識で考えましょう…前半は非常に賛成なのだが、後半は実体験からそうでもないなぁというのがあったりする。
とりあえず「日本国内で勉強する」ということに絞るとすれば、当てはまるのかもしれないが、E○Cとかの英会話学校だと「高いけど先生はまともじゃない」なんてことがままある。実際僕も日本で英会話学校にいっていたのだが、あまりたいした成果はなかったような気がする。もちろん0ではないし、その後カナダに行った際に役に立ってはいたので無駄ではなかったとは思うが。この場合はおそらくここで言う「まともな先生」というのがキーワードなんだろう。それを探すのにスキルがいるということだ。
個人的に上記はとりあえず僕が思ったものでも小さいもので、大きくそれは違うだろうと思ったのは、この文章から見て取れた「金を払わないと英語は習得できない」というもの。(国語の点数は低い方だったのでそんなこと言ってないと言われると以下は破綻します)。
僕がある程度(ビジネスでも使える程度)英語が喋れるようになったのは高い金を払って先生から授業を受けたからではない。どちらかといえばそのような環境にいるからだと思っている。つまり英語で仕事をする環境にいるということ。同じことが日本で働いていた時にも言えて、大学を卒業してから身につけた日本語というものが非常にたくさんある。(御社とか弊社とか学生時代は知らんかった)
「習うより慣れろ」という言葉があるように実際に使われている言葉に触れるというのは何者にも代え難い勉強方法ではないだろうか。ただこれを言うと、
勉強なら他所でやれ
この学生の間違いは、会社に入って給料を貰いながらスキルアップしようと思っていること。小学生から大学まで16年学ぶ時間がありました。就職して仕事を するということは、学んだことを生かしてアウトプットするということ。まだスキルが足りないというのなら、その必要なスキルが学べる専門学校にでも行けば いい。会社に入ってスキルアップなんて図々しいことこの上なく、給料は貰うどころか、授業料を払うべきです。会社でのスキルアップというのは仕事の結果と してそうなるわけであり、それ自体を目的にするのは本末転倒。上記の意見に当てはまる気がするのでそれはそれで微妙かもしれないが。ただ、現場で使われている言葉という点に焦点を絞るならそこにいなければわからないこともあるだろうということだ。
実際、僕もここで働き始めて英語の勉強をせざるを得なかった。具体的には電話の応対とかね。そうはいってもそれに対して金は払ってない(ネット代は含まない)。
効率という点を除けば手段はいくらでもあるはずだ。
「まともな先生」というのが人間以外も指すなら、高い金を除いて賛成ではあるが。
2012-02-12
BNFを書いてみた
Daring Fireball: MarkdownのDingusにあるチートシートからBNFを起こしてみた。無ければ作るのがナンとやら精神で。
> Markdownに詳しい方
間違っている可能性が大いにあるので突っ込み大歓迎ですm(_ _)m
BNF of Markdown,
Doc ::= Element*
Element ::= Paragraph | Header | List | Blockquote | Line
| CodeBlock | BlockHtml | Reference
Paragraph ::= Inline* Linefeed{2,}
Inline ::= (Text | Emphasis | Link | Image | CoseSpan )
Header ::= Setext-Style | Atx-Style
Setext-Style ::= Text Linefeed ('=' | '-')+
Atx-Style ::= '#'{1,6} Text '#'*
List ::= (Number '.' SP+ Inline+) (Linefeed List)*
| ('*' SP+ Inline+) (Linefeed List)*
Blockquote ::= '>' SP* Paragraph
| '>' SP* Linefeed (Blockquote)*
Line ::= ( (SP* '-') | (SP* '*') ){3,} Linefeed
CodeBlock ::= SP{4,} Inline+ Linefeed
BlockHtml ::= '<' (div|p|table|pre) '>' (Text | BlockHtml)+
'<' '/' (div|p|table|pre) '>'
Text ::= ANY
Emphasis ::= '*' Text '*' | '**' Text '**'
| '_' Text '_' | '__' Text '__'
Link ::= '[' ID ']' '(' URL ('"' Text '"')? ')'
ID ::= Text
Image ::= '!' '[' ID ']' '(' URL ('"' Text '"')? ')'
Reference ::= SP{0,3} '[' ID ']' ':' URL ('"' Text '"')?
実装にある正規表現を追ったわけではないのでかなり微妙かつ、BNFの書き方をあんまり良く知らないので正しくはないかも。ルールに書いてないもので、SPとANYはそれぞれスペースと文字(二つ以上続く改行を除く)。Linefeedは改行で。> Markdownに詳しい方
間違っている可能性が大いにあるので突っ込み大歓迎ですm(_ _)m
2012-02-11
Markdownがいるのだが
一つ前の投稿に関連するのではあるが、Markdown形式で書かれたテキストをHTMLに変換するスクリプトがいる。本家を使えばいいといえばそうなのだが、それでは面白くないのと、ちょっとした理由でSagittarius上のライブラリとしてほしいわけだ。
っでとりあえずいろいろな実装をみてみたが、どれもこれも正規表現でテキストからHTML一気に(まぁ多少ごにょごにょしているが)変換している。そんな中peg-markdownはCで書かれているがPEGでパーサーを作成している。とりあえず参考になるかもしれないと思い文法ファイルを見てみたが、信じられないぐらい複雑な文法をしていた。
正直あんな複雑な文法をガリガリPackratで記述するよりは手書きでパーサー書いた方が早い気がする。あとPackratは割りと機能が足りてない感じがするのでどうしても冗長に書いてやらないといけなくて結構大変というのもある。これはCSVのパーサ書いて感じた。あんな簡単な文法なのに結構面倒だった。
一番楽なのはshowdown辺りの実装を移植することかなぁと思っている。っがテキスト→HTMLと一括でやっちゃうのは正直面白くなくて、テキスト→AST→HTMLと一枚噛ませたいなぁと思っている。問題はこれだと正規表現とは非常に相性が悪く、自前パーサーが必要になる。とりあえず動くものなら前者の実装でもいいのだが、う~ん。
誰か簡単なBNF定義してくれないかなぁ・・・(他人任せ)
っでとりあえずいろいろな実装をみてみたが、どれもこれも正規表現でテキストからHTML一気に(まぁ多少ごにょごにょしているが)変換している。そんな中peg-markdownはCで書かれているがPEGでパーサーを作成している。とりあえず参考になるかもしれないと思い文法ファイルを見てみたが、信じられないぐらい複雑な文法をしていた。
正直あんな複雑な文法をガリガリPackratで記述するよりは手書きでパーサー書いた方が早い気がする。あとPackratは割りと機能が足りてない感じがするのでどうしても冗長に書いてやらないといけなくて結構大変というのもある。これはCSVのパーサ書いて感じた。あんな簡単な文法なのに結構面倒だった。
一番楽なのはshowdown辺りの実装を移植することかなぁと思っている。っがテキスト→HTMLと一括でやっちゃうのは正直面白くなくて、テキスト→AST→HTMLと一枚噛ませたいなぁと思っている。問題はこれだと正規表現とは非常に相性が悪く、自前パーサーが必要になる。とりあえず動くものなら前者の実装でもいいのだが、う~ん。
誰か簡単なBNF定義してくれないかなぁ・・・(他人任せ)
ChickenのPackrat
Markdownのパーサーがいるのでpackratを使ってパーサを書こうとしたのだが、いまいち使い方が分からなかった。なので、練習がてらCSVのパーサを書いてみることにしてみた。
とりあえずいい加減なパーサがこんな感じ。
かなり適当で本来はCRLFなのがLFだけだったり、エスケープされたものを認識しなかったりするがまぁ動く。気になったのは「/」の使い方で、こんな感じには使えないという不便さであった。
やっぱり正規表現をつかってやるべきだろうか。
とりあえずいい加減なパーサがこんな感じ。
(import (rnrs)
(packrat)
(srfi :14 char-set))
(define *text-set*
(ucs-range->char-set! #x2d #x7e #f
(ucs-range->char-set! #x23 #x2b #f
(ucs-range->char-set #x20 #x21))))
(define (any results)
(let loop ((acc '()) (results results))
(let ((ch (parse-results-token-value results)))
;; it's just testing
(if (and ch (char-set-contains? *text-set* ch))
(loop (cons ch acc) (parse-results-next results))
(make-result (list->string (reverse! acc)) results)))))
(define (textdata results)
(any results))
(define parser
(packrat-parser
(begin
(define (crlf results)
(let ((ch (parse-results-token-value results)))
(case ch
((#\linefeed) (make-result "" results))
((#\return)
(let ((ch (parse-results-token-value (parse-results-next results))))
(if (char=? #\linefeed ch)
(make-result "" results)
(field-entry results))))
(else (field-entry results)))))
file)
(file ((h <- header '#\linefeed r <- records) (cons h r))
((r <- records) r))
(header ((n <- names) (cons :header n)))
(records ((f <- fields '#\linefeed r <- records) (cons (cons :record f) r))
((f <- fields) (list (cons :record f))))
(fields ((f <- field-entry '#\, fs <- fields) (cons f fs)) ;; (1)
((f <- field-entry) (list f)))
(names ((n <- field-entry '#\, ns <- fields) (cons n ns))
((n <- field-entry) (list n)))
(field-entry ((e <- textdata) e))))
(define (generator p)
(let ((ateof #f)
(pos (top-parse-position "")))
(lambda ()
(if ateof
(values pos #f)
(let ((x (read-char p)))
(if (eof-object? x)
(begin
(set! ateof #t)
(values pos #f))
(let ((old-pos pos))
(set! pos (update-parse-position pos x))
(values old-pos (cons x x)))))))))
(define (parse-csv p)
(let ((result (parser (base-generator->results (generator p)))))
(if (parse-result-successful? result)
(parse-result-semantic-value result)
(apply assertion-violation
(let ((e (parse-result-error result)))
(list 'parse-csv
(parse-error-messages e)
(parse-position->string (parse-error-position e))
(parse-error-expected e)))))))
(call-with-input-file "test.csv"
(lambda (p)
(parse-csv p))))
#|
入力ファイル
aaa,bbb
ccc,ddd,eee
fff,ggg,hhh
a,b,c
出力
((:header "aaa" "bbb")
(:record "ccc" "ddd" "eee")
(:record "fff" "ggg" "hhh")
(:record "a" "b" "c"))
|#
generatorはドキュメントにあったものをちょっと改変しただけ。多分これが基本なんだろう。かなり適当で本来はCRLFなのがLFだけだったり、エスケープされたものを認識しなかったりするがまぁ動く。気になったのは「/」の使い方で、こんな感じには使えないという不便さであった。
(entry (((/ (e <- escaped) (ne <- non-escaped))) (if e e ne)))展開されたコードをみたらまぁ納得なのだが、これがやれないとなると結構面倒だよなぁ。あとこのライブラリは「*」とか「+」とか「?」がないので、それらを書こうと思ったら、(1)のように条件を2つ作る必要がある。
やっぱり正規表現をつかってやるべきだろうか。
2012-02-09
srfi-22
現状部分的に実装しているのだが、もう少しまじめに実装するべきだろうか。単にmain関数を特別視するかどうかというだけだが。
正直実装自体は非常に簡単なので(2~3行足すだけ)やるなら悩むことも無く終わるのだが、どうしよう。毎回(command-line)を呼び出すよりは(main args)と書いて参照できた方が楽だよなぁ。特に使い捨てのスクリプトならなおさら。
やるか。
正直実装自体は非常に簡単なので(2~3行足すだけ)やるなら悩むことも無く終わるのだが、どうしよう。毎回(command-line)を呼び出すよりは(main args)と書いて参照できた方が楽だよなぁ。特に使い捨てのスクリプトならなおさら。
やるか。
Subscribe to:
Posts (Atom)