JScript高速化(14)

元々何をしようとしているか思い出しておこう。


0<x<1で1、その他で0の関数の
畳込み9回繰り返したときの厳密な関数を求めたが、
これが遅いので高速化していたのだった。


今までの結果を組み込んで動かしてみよう。
係数が有理数でなく実数のバージョンを100回計算すると、
65328ms→4453msとなった。

積分

今ここのメソッドがどうなっているかというと、


function poly_integral() {
var args = this.integral.arguments;
if(args.length == 0) { // 不定積分
var r = [ 0 ];
for(var i = 0; i < this.length; i++)
r[i+1] = this[i] / (i + 1);
return r;
}
else if(args.length == 2) { // 定積分
var r1 = [ ];
var q = this.integral(); // とりあえず不定積分する

for(var i = 0; i < 2; i++) {
var a = args[i];
if(a instanceof poly) // 多項式なら合成
r1[i] = q.synthesize(a);
else
r1[i] = q.value(a);
}

// 種類によって引き算を場合分け
if(r1[1] instanceof poly) {
return r1[1].subtract(r1[0]);
}
else {
if(r1[0] instanceof poly)
return [r1[1]].subtract(r1[0]);
else
return r1[1] - r1[0];
}
}
else
throw("wrong number of arguments in poly::integral");
}

見ただけでかなりひどいが、
いつものように、
プロパティはなるべく参照しないようにして、
argumentsオブジェクトも使わずに、
あと、帰納的に使うのはやめると次のようになる。


// 4110ms
function poly_integral(a1, a2) {
// とりあえず不定積分する
var r = [ 0 ];
for(var i = this.length - 1; i >= 0; i--)
r[i+1] = this[i] / (i + 1);

if(a1 == undefined) { // 不定積分
return r;
}
else if(a2 != undefined) { // 定積分
var r11, r12;

if(a1 instanceof poly) // 多項式なら合成
r11 = r.synthesize(a1);
else
r11 = r.value(a1);
if(a2 instanceof poly) // 多項式なら合成
r12 = r.synthesize(a2);
else
r12 = r.value(a2);

// 種類によって引き算を場合分け
if(r12 instanceof poly) {
return r12.subtract(r11);
}
else {
if(r11 instanceof poly)
return [r12].subtract(r11);
else
return r12 - r11;
}
}
else
throw("wrong number of arguments in poly::integral");
}

意外と速くならない。
別の遅い要因があるらしい。