LoginSignup
3
1

More than 5 years have passed since last update.

immutable-js の Seq は本当に lazy か

Last updated at Posted at 2015-12-17

TL;DR

  • ドキュメント上、 immutable-js の Seq は lazy とされているけれど、それってミスリーディングなのではなかろうか?
  • lazy という表現から期待すること
    1. 変数の値や関数の結果が、実際にアクセスされるまで評価されない
    2. 一度アクセスされた後は評価値がキャッシュされ、二回目以降のアクセスでは再評価が発生しない
  • immutable-js の Seq は上記の 1 しか満たしていない
    • それって lazy というより単に都度計算しているだけでは?
    • とはいえ、評価値のキャッシュすると、多くの場合パフォーマンスはむしろ低下しそうなので、挙動として悪いわけではないと思う
    • 毎回評価しなおしちゃうよ、ということを分かりやすいところに書いておいて欲しい

Seq の挙動の確認

  1. ブラウザの開発者ツールを開き、コンソールに immutable-js のコード を張り付ける
  2. コンソールで下記を実行して出力を確認する
var mappedSeq = Immutable.Seq([0,1,2]).map(function(num){console.log('map called'); return num * 2;});
mappedSeq.get(0); // logs 'map called'
mappedSeq.get(0); // logs 'map called' again!

Seq の挙動の評価

実は以前、上に記載した lazy から期待する 2 つの仕様を満たした配列を、 JavaScript で実装するというのを試したことがあります。

このとき、パフォーマンスの計測もしたのですが、結果としては、ほとんどのケースでは他の実装 (native な Array を含め) と比較したパフォーマンス上のメリットはなさそう、というものでした。
これは、評価値をキャッシュするために余計なオブジェクト、関数を生成する必要があるため、 map や filter といった処理を大量に実行したり、値へのアクセスを何度も繰り返すようなことをしない限り、コストに見合うメリットを得られないためと考えられます。
(もちろん、単に私の実装がイケてないだけな可能性もありますが。。。)

上記の経験から、 immutable-js の Seq が評価値をキャッシュしない挙動になっていることは、正しい決断だと思っています。
ただ、この挙動で lazy と言ってしまうのはミスリーディングだと思うので、分かりやすいところに説明が欲しいです。
(一応あるけどそんなに目立たない)
実際、再評価なんてされないと思い込んでいた人いませんか?いますよね?きっといるはず。

なお、評価値をキャッシュする実装も検討されている模様

issue に上がっています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1