require_remote
にかかる時間がさすがに長すぎるので、なんとかしたい……。
開発効率的にも辛いですし、他の人に見てもらうときもなるべく待たせないようにしたい。
というわけで調べてみました。
ネックになっているのは data.rb
のコンパイル時間のようです。
今までのデータでサイズが一番大きいのは step 36 のものなので、今回はこのファイルを使って比較します。
data.rb
のコンパイルにどのくらい時間がかかっているのか
*1
測ってみると、
Firefox で 5回の平均が 22.8 秒でした。うーん、これはひどい。
サイズを見てみます。
- 741 KiB
- 行数: 35,163
うーむ。Opal もこんなものを渡されて大変ですね。
ちなみにこの data.rb
を CRuby で実行してみるとこんな感じでした。
$ ruby -v ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux] $ time ruby data.rb real 0m0.192s user 0m0.107s sys 0m0.095s
単純に大きいので小さくしましょう。
以下は data.rb
の内容の一部です。
{ "edges": [ { "pos1": { "x": 59, "y": 9 }, "pos2": { "x": 60, "y": 22 }, "wfs": [ { "pos1": { "x": 59, "y": 9 }, "pos2": { "x": 60, "y": 9 } }, { "pos1": { "x": 60, "y": 9 }, "pos2": { "x": 61, "y": 9 } },
Point オブジェクトが大量にあります。 まずは これをコンパクトにしましょう。
オブジェクトのフォーマット { ... }
になっていたところをただの文字列にします。
フォーマットの変更なので、 step 38 までのデータとは互換性がなくなりますが、やむなし。
--- a/unit.rb +++ b/unit.rb @@ -9,17 +9,12 @@ module Unit end def to_plain - { - x: @x, - y: @y - } + [@x, @y].join(",") end def self.from_plain(plain) - Point.new( - plain["x"], - plain["y"] - ) + x, y = plain.split(",").map { |s| s.to_f } + Point.new(x, y) end def hash
たとえば上に挙げた箇所がこんな感じでコンパクトになります:
{ "edges": [ { "pos1": "59,9", "pos2": "60,22", "wfs": [ { "pos1": "59,9", "pos2": "60,9" }, { "pos1": "60,9", "pos2": "61,9" },
これで 11.4 秒になりました。
それから、JSON の整形でもかなりサイズが水増しされているので、 整形をやめることに。
--- a/preprocess.rb +++ b/preprocess.rb @@ -21,6 +21,6 @@ circuits = plain = circuits.map { |circuit| circuit.to_plain } puts "$data_json = <<EOB" -print JSON.pretty_generate(plain) +print JSON.generate(plain) print "\n" puts "EOB"
もちろん整形されている方がデバッグ時などに見やすいわけで、 整形をやめるかどうかちょっと悩みました。
しかし、デバッグのために data.rb
を調べなければいけない場面は今までそんなになかったですし、
整形したければまた JSON.pretty_generate
に戻せばよいだけだと考え、やってしまうことにしました。
最終的な前後比較です。
所要時間: requrie_remote "./data.rb" の所要時間 サイズ: data.rb のサイズ before: 所要時間: 22.8 秒 サイズ: 740.8 KiB after: 所要時間: 2.6 秒 ... 88%減 サイズ: 109.6 KiB ... 85%減
かなり縮みました。元がひどかったですね……。
デモ用に 1bit CPU だけのデータを作り直しました。
https://sonota88.github.io/kairo-gokko/pages/39/index.html