Angular 使用 $timeout 的原生去抖对比 lodash_.debounce 基准

Angular native debounce with $timeout vs lodash_.debounce benchmark

想测试哪种方法会更快,使用原生 angular $timeout 或 lodash 内置 _.debounce() 函数的去抖功能。

所以我创建了基准,想问一下,这个基准是否可以被认为是objective,如果不是,应该改变什么才能使两个函数的测试相等?

https://jsfiddle.net/ues8d4pL/

要使用 $timeout 进行测试,行 debounceUpdate({ value: i }, $scope.model); 被使用。

测试 lodash 功能

// 2. Test With lodash
// _.debounce(function() {
//     saveParameters({ value: i }, $scope.model);
// }, 1000)();

行应该取消注释。对我来说,$timeout 花费了 2585.61 毫秒,lodash 花费了 4240.875 毫秒。

这个基准可以被认为是正确的吗?如果不正确,我需要更改什么?

另外,哪种方式更可取,使用原生 $timeout 还是 lodash debounce?

基准测试的执行方式有误。

_.debounce(function() {
    saveParameters({ value: i }, $scope.model);
}, 1000)();

在每次迭代时创建一个新的去抖动函数并立即调用它,它类似于在每次迭代时执行 setTimeout 并且没有任何去抖动效果。 unthrottled 函数在 CPU 上相对较轻的原因是因为它不执行 $rootScope.$apply()(如 $timeout)。

可以直接与$timeout去抖动进行比较的_.debounce的正确用法是

var lodashDebounceUpdate = _.debounce(function() {
    $timeout(function () {
        saveParameters({ value: i }, $scope.model);
    });
}, 1000);

for (...) {
    lodashDebounceUpdate();
}

$timeout 中并没有什么真正的 'native',它只是 wraps setTimeout under the hood 可以在规范中同步执行的方式。

在早期的 Underscore/Lodash 实现中 _.debounce 以类似的直观方式使用 setTimeout

在现代版本中,Underscore and Lodash 都已切换到使用 Date.now() 的实现,并且速度快 ~50000 倍(测量基于私人体外基准)。

所以是的,_.debounce 比自定义的基于 $timeout/setTimeout 的去抖动函数性能更高,如果去抖动函数预计每秒有数百次调用,它可能是有益的。否则这可能被认为是过早的优化。