forked from mruby/mruby
-
Notifications
You must be signed in to change notification settings - Fork 4
IO_memo
akiray03 edited this page Mar 14, 2013
·
14 revisions
- IOのバッファリング等を FILE* に任せる (iij/mrubyのIO実装)
- バッファリングをCでスクラッチ実装する
- バッファリング無しのIO(sysread,syswrite)をRubyメソッドで提供する。バッファリングはmrubyで実装する(かもしれない)
- mrubyの用途として、IOバッファリングってどんなものが求められてる?
- IOの上に乗っかるSocketはバッファリング欲しがるかも
- 小さなデバイスの場合には、そもそもFILE*使えないかもしれない
- 大きなリソースがある場合には、バッファリング云々よりも、全部読んじゃう/行単位で読み進める、でも良いのか。
- fptr->f2 の使われ方 (後で泣かないように!)
- pipeでread/writeが使えるときに、write用に利用している
- select の writers
- バッファリングはmrubyで実装する。IO.syswrite, sysread C言語で実装して提供する。
- IO.new と IO.popen の挙動から確認していく
- 書く側は、IO#write がバッファされるOutputのプリミティブなメソッド。
- write buffer を用意するならば、IO#writeで考慮すれば良い
- だけど、たぶん write buffer は要らない (?)
- 読む側は、バッファされるプリミティブなメソッドが示されていない
- IO#gets, IO#getc, IO#readlines, ... etc は、バッファリングしつつ IO#sysread を呼べばOK
- IO#read も IO#sysread を呼べばOK
- IO#read(size) は、 sizeに達するまで待つ
- バッファリングしつつIO#sysreadを呼ぶ、ユーティリティメソッドを用意する。
- IO#read(size) との違いは、 sizeが maxlength である点
- (maxlengthに達していなくても、読めるだけ読んだら、ブロックせずに返す)
- 指定されたmaxlengthを上限に、IO#sysreadを使ってデータを読み込む
- IO#read(size) と違って、 size に達していなくても、読み込むデータが無くなれば、そこまでのデータを返す
- EOFに達した時は EOFError を返す (IO#sysreadと同じ)
- maxlengthは、バッファサイズ(BUF_SIZE)以下でなければならない (maxlength <= BUF_SIZE)
-
IO.new で指定する mode
- "r" や "w" など (String) ... (1)
- File::Constants::RDONLY など (Integer) ... (2)
-
open(2) に渡す mode ... (3)
-
mrubyのIO実装で条件判定に用いる flag ... (4)
-
このうち、 (2) と (3) は同じ
-
以下のように名前を付ける
- modestr : "r" や "w" など
- modenum : open(2)に渡すmode
- flags : mrubyのIO実装で条件判定に用いるflag (FMODE_XXX として mruby/ext/io.h で定義)
to\from | modestr | modenum | flags |
---|---|---|---|
modestr | x | x | x |
modenum | x | x | o |
flags | o | o | x |
- 実装する変換関数
- static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr)
- static int mrb_io_modenum_to_flags(mrb_state *mrb, int modenum)
- static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
t1 = Time.now
10000.times do
fd = IO.sysopen("AUTHORS")
io = IO.new(fd)
ary = []
while (line = io.gets)
ary << line
end
io.close
end
puts "gets: #{Time.now - t1}sec"
t1 = Time.now
10000.times do
fd = IO.sysopen("AUTHORS")
io = IO.new(fd)
io.read
io.close
end
puts "read: #{Time.now - t1}sec"
- iij/mruby ... gets: 0.8sec, read: 0.23sec
- mruby/mruby + mruby-io ... gets: 1.8sec, read: 0.28sec
- ruby1.9.3 ... gets: 0.3sec, read: 0.23sec
repo | gets | read |
---|---|---|
iij/mruby | 1.401791sec | 0.186041sec |
mruby-io before | 1.695227sec | 0.283898sec |
mruby-io after | 0.778406sec | 0.249566sec |
ruby1.9.3 | 0.287875sec | 0.258772sec |