Javascriptでカプセル化を実現する!の続編みたいなものです。
この記事を投稿したところ、chokodogさんから次のような指摘を受けました。
(コメントありがとうございます><)
カプセル化した場合、コンストラクタ内でメソッドが定義されているので、new するたびfunctionが定義され、prototypeで定義するよりメモリを多くとられてしまうということはないのでしょうか?
たしかにそのとおりです。
今回はカプセル化を先のような方法で行うとどのようなコストがかかるのかということ探ってみました。
chokodogさんの指摘の意味を簡単に説明したいと思います。
まずは以下のjavascriptのプログラムを見てください。
JavaScriptは通常のクラスベースのオブジェクト指向とことなりプロトタイプベースという別のプログラムパラダイムを採用しています。
JavaScriptのオブジェクトはすべてハッシュのようなものになっていますが、これに少しばかり細工がしてあります。
それがプロトタイプチェーンというやつです。
オブジェクトは、自身のプロパティで見つからないようなハッシュ値を自分自身のコンストラクタのプロトタイプへと探しにいきます。
たとえば、上のプログラムの場合、
objpropというプロパティを探しにいったときに
・自分自身のプロパティではない
・自分のコンストラクタのプロトタイププロパティではない。
・チェーンの終端であるオブジェクトのプロトタイププロパティで発見
というような順番で探っています。
しかし、次のようにするとプロトタイプ経由のプロパティを自分自身のプロパティとして利用することができます。
さて、プロトタイプチェーンの仕組みを踏まえて
次のようなプログラムを見てください。
このように、オブジェクトのメソッドを定義する際に、
オウンプロパティとして実装する場合では、
2つのインスタンスの定義した関数のそれぞれのさすリファレンスがことなることがわかります。
リファレンスとはC言語でいえばポインタ。
つまりコンピュータのメモリ上の格納場所が異なるということです。
なので、
カプセル化した場合、コンストラクタ内でメソッドが定義されているので、new するたびfunctionが定義され、prototypeで定義するよりメモリを多くとられてしまうということはないのでしょうか?
冒頭のこのようなコメントを頂戴するわけです。
このコメントに対して、僕はあろうことか鼻くそほじるように
「トレードオフじゃないですか~。サーセンwwフヒヒ」(嘘おおげさ紛らわしい)と答えてしまいました。
やっぱりどのくらいコストがかかるのか確かめてみようと思い、実験を行いました。
二つのjavascriptプログラムの実行時間とメモリ消費量を調べる。
この2つのプログラムの生成にかかるコストをこのような
プログラムをそれぞれに行い調査します。
# time js none.js real 0m0.006s # time js cap.js real 0m0.007s # time js underbar.js real 0m0.007s # time js c_cap_10000.js real 0m1.741s # time js c_underbar_10000.js real 0m0.867s
jsインタプリタにはspidermonkeyを使います。
none.jsはただjsインタプリタを起動するのにかかった時間をはかるために何も書いていないjsファイルをtouchして作っただけです。
読み込みにはそれぞれ0.001secしかかかっていません。
実行時間は10000個のインスタンス生成におよそ0.874秒のコストがかかっています。
ということは、カプセルかによって
87.4マイクロ秒
のコストが1つのインスタンス生成あたりにかかっているようです。
次はメモリの消費量です。
これは昨日作ったfleafeedを使ってみます。
C言語でメモリ使用量をカウントする!
timeコマンドのオプション使えやって思った人は正しいんですが、
せっかくなので使ってみたくなっちゃったんだもん><
#fleafeed js none.js < fleafeed > -----------fleafeed results------------ --USING HEAP : 48574 bytes #fleafeed js cap.js -----------fleafeed results------------ --USING HEAP : 59641 bytes # fleafeed js underbar.js -----------fleafeed results------------ --USING HEAP : 56019 bytes # fleafeed js c_cap_10000.js -----------fleafeed results------------ --USING HEAP :12925508 bytes # fleafeed js c_underbar_10000.js -----------fleafeed results------------ --USING HEAP : 1731685 bytes
とこんな感じ。
jsの実装はほとんどHEAPしか使わないので、HEAP領域のみをピックアップしてみました。
まず、読み込みにかかるコストの比較ですが
アンダーライン記法:11067 bytes クロージャ記法 :7745 bytes
あれ?なんかしらんけどクロージャ記法のほうが読み込みは少ないっぽいです。不思議。
次に生成1つあたりのメモリコストの違いですが
これはでかいですね。
これを計算してみると1つあたりのメモリコストは
1,110 bytes
となっているようです。およそ1kのメモリが余分に使われてしまうわけです。
これは確かにコスト高な感じはします。
富豪プログラミングをしたいひとにはオススメということで
どうでしょうか(泣)
« twitterの正しい使い方 – 野望の会が学会デビュー。 »
No comments yet.