ファイル読み書きはどれくらい遅いのか(追記あり)

 - by Don

YAYAで測定

ファイルの読み書きは遅いというのは体感的に何となく知っているのですが、どのくらい遅いのか調べてみようと思いました。

実験で使用するSHIORIはYAYA。関数のFREADFWRITEをそれぞれ1,000,000回実行して掛かった時間を測定します。ループ自体に掛かる時間や代入処理に掛かる時間なども比較のために測定します。

ループだけの処理//2秒
{
  _n = 1000000

  _start = GETTIME[6]
  for _i = 0; _i < _n; _i++ {
    //何もしない
  }
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}

代入処理//4秒
{
  _n = 1000000

  _start = GETTIME[6]
  for _i = 0; _i < _n; _i++ {
    _hoge = _i //代入
  }
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}

読み//10秒
{
  _filename = 'xxx'
  _n = 1000000

  _start = GETTIME[6]
  if !FOPEN(_filename, 'r')
    return
  for _i = 0; _i < _n; _i++ {
    _line = FREAD(_filename) //読む
  }
  FCLOSE(_filename)
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}

書き//10秒
{
  _filename = 'xxx'
  _n = 1000000

  _start = GETTIME[6]
  if !FOPEN(_filename, 'w')
    return
  for _i = 0; _i < _n; _i++ {
    FWRITE(_filename, 'hoge') //書く
  }
  FCLOSE(_filename)
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}

ループだけでもカウンタ_iがインクリメントされるのでその処理時間が掛かっているように見受けられます(代入処理を加えるとちょうど2倍の時間になっています)。ファイルのオープン/クローズのオーバーヘッドの影響がこの例ではほぼ無視されてしまいますがそれでもそれなりに時間が掛かっているようです(ファイルの開け閉めを同じ回数だけ回すとさらに2倍くらいかかります)(←勘違い)

追記

やっぱりFOPEN/FCLOSEまで含めての実験が必要ですね。ということで

読み//202秒
{
  _filename = 'xxx'
  _n = 1000000

  _start = GETTIME[6]
  for _i = 0; _i < _n; _i++ {
    if !FOPEN(_filename, 'r')
      return
    _line = FREAD(_filename) //読む
    FCLOSE(_filename)
  }
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}
書き//1510秒?(100,000回ループの値を10倍しました)
{
  _filename = 'xxx'
  _n = 1000000

  _start = GETTIME[6]
  for _i = 0; _i < _n; _i++ {
    if !FOPEN(_filename, 'w')
      return
    FWRITE(_filename, 'hoge') //書く
    FCLOSE(_filename)
  }
  _end = GETTIME[6]

  '\0\s[0]\_qstart: ' + _start + '\nend: ' + _end
}

他のSHIORIとの比較

前回の里々での実験においてループ回数を揃えて並べれば、SHIORIの処理能力の比較ができそうな気がします。

*nop関数
:[開始](現在秒)(loop,loop_nop,1000000)
[終了](現在秒)#82秒

*set関数
:[開始](現在秒)(loop,loop_set,1000000)
[終了](現在秒)#138秒

@loop_nop
(nop,)

@loop_set
(set,hoge,)

遅いですね。びっくりです。

ついでに華和梨でも調べてみます。

# ループのみ(1秒)
sample1: \0\s[0]\_qstart: $(date %S)$(loop 1000000 "")\nend: $(date %S)\e

# エコー関数(6秒)
sample2: \0\s[0]\_qstart: $(date %S)$(loop 1000000 $(echo ""))\nend: $(date %S)\e

# 代入関数(8秒)
sample3: \0\s[0]\_qstart: $(date %S)$(loop 1000000 $(setstr foo bar))\nend: $(date %S)\e

ループ自体では関数呼び出し1回のみで他の関数呼び出しが無い分高速のようです。代入などの関数をコールすればそれなりの時間を要するみたいです。

まとめ

表にすると見やすいかもしれない。

処理内容(1,000,000回) 時間(秒)
YAYA ループのみ(for) 2
YAYA 代入 4
YAYA ファイル読み(FREAD) 10
YAYA ファイル書き(FWRITE) 10
YAYA ファイル読み(FOPEN,FREAD,FCLOSE) 202
YAYA ファイル書き(FOPEN,FWRITE,FCLOSE) 1510(?)
里々 何もしない関数(nop) 82
里々 代入関数(set) 138
華和梨 ループのみ 1
華和梨 エコー関数(echo) 6
華和梨 代入関数(setstr) 8

ファイル読み書きの遅さの検証のはずが里々の遅さにびっくりする結果となりました。ファイル読み書きが逆に高速に見えてしまいます。こんなはずでは。

複数のファイルを開け閉めするのはそれなりに時間がかかるようですが、1つのファイルに何万行読み書きしてもそれ自体はあまり時間はかからないようです。

でも実用上1,000,000回もループする処理なんて普通のゴースト開発ではまずあり得ないですね。

No comments yet.