はじまり
以前から気になっていたeachlineを使うか、readlinesをつかうか問題。「趣味の問題」と片づけていたが、処理スピードに差があるとしたら、そうも言ってられない。
というわけで、「eachline」と「readlines」で同じ処理を行い、処理時間を比較してみた。
負荷の定義
まずは、処理時間の差につながるプログラムの「負荷」を定義してみたい。
負荷は、「CPU負荷」と「IO負荷」の2種類に大別されるが、今回は前者の「CPU負荷」について考えてみたい。
負荷は、「CPU負荷」と「IO負荷」の2種類に大別されるが、今回は前者の「CPU負荷」について考えてみたい。
「CPU負荷≒CPU使用率」これも2種類(「システムCPU時間」と「ユーザCPU時間」)とにわけられる。
「システムCPU時間」はシステムコール等の実行に費やした時間の合計、
「ユーザCPU時間」はそれ以外(超ざっくりです)
よって、OSの機能を呼び出さない限り、システムCPU時間はゼロのままとなる。
また、上述のキーワードは、以下のように言い換えることができる。
システムCPU時間(UserTime) = カーネル空間(スペース)
ユーザCPU時間(SystemTime) = ユーザ空間(スペース)
CPU時間と空間。一見違う種類の言葉に見えるが、ネットの記事をいろいろ見ていると、どうも同じコンテキストで使われているようだ。
「システムCPU時間」はシステムコール等の実行に費やした時間の合計、
「ユーザCPU時間」はそれ以外(超ざっくりです)
よって、OSの機能を呼び出さない限り、システムCPU時間はゼロのままとなる。
また、上述のキーワードは、以下のように言い換えることができる。
システムCPU時間(UserTime) = カーネル空間(スペース)
ユーザCPU時間(SystemTime) = ユーザ空間(スペース)
CPU時間と空間。一見違う種類の言葉に見えるが、ネットの記事をいろいろ見ていると、どうも同じコンテキストで使われているようだ。
ユーザスペースでプログラムが実行されたときの時間
測定
以下のコードで各スペースでの処理時間の測定を行なった。時間測定には「benchmarkモジュール」を利用した。```rb
require 'benchmark'
Benchmark.bm 10 do |r|
i = 0
r.report "open + each" do
File.open("test.txt").each_line do |j|
j
end
end
r.report "readlines" do
File.readlines("test.txt").each do |j|
j
end
end
end
```
eachlineとreadlinesの実装の違い
cのソースコードで実装の違いを確認してみる。まずはreadlines。
readlines : io_s_readlines => rb_io_readlines => rb_io_getline_1
の順で関数を呼び出して、1行ずつフェッチして、arrayに追加、最後にarrayを返却。
続いてeach_line。
each_line : rb_io_each_line => rb_io_getline_1
で1行ずつブロックにyieldするだけ。よって1行ずつストアして行列を拡大させる処理が必要ない。よって早いはず??
以下はスタックオーバーフローでの質問回答
Digging into the source, readlines is implemented by io_s_readlines which calls rb_io_readlines. rb_io_readlines calls rb_io_getline_1 to fetch line and rb_ary_push to push result into the returning array.
each_line is implemented by rb_io_each_line which calls rb_io_getline_1 to fetch line just like readlines and yield the line to your logic with rb_yield.
So, there is no need to store line results in a growing array for each_line, no array resizing, copying issue.
結果
概ね「readlines」が約2倍遅い結果となった。
(※まったく逆の結果readlinesが2倍早くなる場合もあったが原因は不明。)
(※まったく逆の結果readlinesが2倍早くなる場合もあったが原因は不明。)
user system total real
open + each 0.016000 0.000000 0.016000 ( 0.021503)
readlines 0.031000 0.000000 0.031000 ( 0.028004)
No comments:
Post a Comment