5

私の質問は、関数のインライン化による最新のブラウザーの最適化に関するものです。この質問に答えるには、V8、JavaScriptCore、SpiderMonkeyコードベースに精通している人が本当に必要だと思います。または、少なくとも、最適化への最新のブラウザアプローチに精通している人。

基本的に、関数のインライン化がいつ使用されるかを予測する方法があるかどうか、および最小限のコード重複でパフォーマンスを最適化するためにそれを活用する方法を知りたいです。

例として、joitempoから次の単純な関数を取り上げましょう。

function limit(f, max) {
    var count = 0, isFunction = typeof max == 'function';
    if(!isFunction) max = max >>> 0 || 1;
    return function limitedFunction() {
        if(isFunction ? !max(count) : (count >= max)) return;
        count++;
        return f.apply(this, arguments);
    };
}

この関数は関数を受け取り、fラッパー関数を返します。ラッパー関数は、ラッパーを介して元の関数を呼び出すことができる回数を制限します。例:

var foo = limit(function() { console.log('foo'); }, 3);
foo(); // logs 'foo'
foo(); // logs 'foo'
foo(); // logs 'foo'
foo(); // doesn't log anything
foo(); // doesn't log anything

また、(数値の代わりに)2番目の引数としてtrueまたはを返す関数を受け入れます。false

var bar = limit(
    function() { console.log('bar'); },
    function() { return Math.random() > 0.5 ? true : false }
);
bar(); // randomly logs 'bar' or doesn't log anything
bar(); // randomly logs 'bar' or doesn't log anything
bar(); // randomly logs 'bar' or doesn't log anything

これは非常に単純で些細な例なので、我慢してください。これには重要なケースで実際のアプリケーションがあると思いますが、簡単なケースを使用して、ブラウザーがインライン化を実行する方法または実行できる方法の根本を理解したいと思います。

パフォーマンスを(おそらく)(非常にわずかに)改善できるこの関数を書き直す1つの方法は、返された関数functionを2つのケースに分けることです。1つmaxは関数で、もう1つmaxは数値です。

function limit(f, max) {
    var count = 0, isFunction = typeof max == 'function';
    if(!isFunction) max = max >>> 0 || 1;
    return isFunction
        ? function limitedFunctionA() {
            if(!max(count)) return;
            count++;
            return f.apply(this, arguments);
        }
        : function limitedFunctionB() {
            if(count >= max) return;
            count++;
            return f.apply(this, arguments);
        };
}

このようにして、毎回発生するかどうかisFunctionを確認するチェックが呼び出されますが、戻るかどうかが決定されたときに1回だけ呼び出されます。ただし、冗長なコードがあるため、これは理想的ではありません。truefalse limitedFunctionlimitedFunctionAlimitedFunctionB

私の質問は、次の書き直しに関するものです。

function limit(f, max) {
    var count = 0, isFunction = typeof max == 'function',
        check = isFunction
            ? function() { return !max(count); }
            : function() { return count >= max; };
    if(!isFunction) max = max >>> 0 || 1;
    return function limitedFunction() {
        if(check()) return;
        count++;
        return f.apply(this, arguments);
    };
}

だからここに私の質問があります...現代のブラウザは回るのに十分賢いですか

if(check()) return;

の中へ

if(!max(count)) return;

いつisFunctionが真であり、

if(count >= max) return;

いつisFunction偽ですか?...余分な関数を呼び出す必要をなくし、check()毎回不必要に余分な関数をスタックにスローします。

4

0 に答える 0