我的问题涉及通过函数内联进行现代浏览器优化。我想我真的需要熟悉V8,JavaScriptCore和/或SpiderMonkey代码库的人来回答这个问题。或至少知道现代浏览器优化方法的人。
基本上我想知道是否有任何方法可以预测何时使用函数内联以及如何利用它来优化性能,而且代码重复最少。
让我们以joi速度为例,采用以下简单函数:
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
它还接受一个函数,它返回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
这是一个过于简单,琐碎的例子,所以请耐心等待。我认为在非平凡的情况下有真正的应用程序,但我想用一个简单的案例来了解浏览器如何或可以进行内联的根。
重写此函数的一种方法是(可能)(非常轻微地)改进性能(我想)将返回的function
分成两种情况,一种max
是一种情况函数和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
时,检查true
false
是limitedFunction
还是limitedFunctionA
都不一定要发生但是只有在确定是返回limitedFunctionB
还是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()
为false时? ...无需调用额外的{{1}}函数,每次都不必要地在堆栈上抛出额外的函数。