JScript高速化(6)

prototype

昨日のはメソッドを書いていなかったから、
それを書き足すと、


// 5027ms
function poly(a) {
...

this.copy = poly_copy;
this.add = poly_add;
this.subtract = poly_subtract;
this.multiply = poly_multiply;
this.value = poly_value;
this.synthesize = poly_synthesize;
this.integral = poly_integral;
this.normalize = poly_normalize;
this.toString = poly_toString;
}

メソッドをこうして書くのは、
コンストラクタを呼ぶごとにプロパティを追加するから
コストがかかる。
次のようにすると、最初にプロパティを追加するだけで済む。


poly.prototype.copy = poly_copy;
poly.prototype.add = poly_add;
poly.prototype.subtract = poly_subtract;
poly.prototype.multiply = poly_multiply;
poly.prototype.value = poly_value;
poly.prototype.synthesize = poly_synthesize;
poly.prototype.integral = poly_integral;
poly.prototype.normalize = poly_normalize;
poly.prototype.toString = poly_toString;

これで3791ms。


追記
以下は間違いだった(11/8)。


だいぶ速くなったが、
さらに速くできないだろうか。
多項式は、データだけ見ると配列なので、
Arrayにメソッドを追加してみる。
まず、


poly = Array;

とすると、polyはArrayと同じことになる。
これにさきほどと同じようにメソッドを追加する。


poly.prototype.copy = poly_copy;
...
poly.prototype.toString = poly_toString;

と、ここでコピーメソッドを書きたいが、
各要素にどのようにアクセスしたらいいか分からない。


function poly_copy() {
var r = new poly();
for(var i = this.length - 1; i >= 0; i--)
r[i] = this[i];
return r;
}

これはエラーになる。
もちろんこれならいいが。


return this.slice(0);

これで、3141ms。
このメソッドを使うのが遅いことは分かっている。
他に方法はないだろうか。
だが、ECMAのリファレンスを見ても、
各要素にアクセスをする方法は書いていないようだ。


http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf


はたと思いついて、こうやってみた。


r[i] = this[""+i];

すなわち、数値ではアクセスできないが、
文字列に変換すると可能になるのだ。
Arrayは配列ではなくたぶんハッシュなので、
数値も文字列に変換されてから要素にアクセスされる。


これは、結構知られていないトリビアではないだろうか。


しかし、こうすると4047msととても遅い。


r[i] = this[i.toString()];

これだと5516msとさらに遅い。