淘汰赛可观察量和性能

Knockout observables and performances

本文关键字:性能 观察 淘汰赛      更新时间:2023-09-26

我已经使用淘汰赛一年多了,但仍然有一个问题我无法解决。这与其说是实际问题,不如说是"语法糖"问题。代码简单在TypeScript中,但应该没问题,即使你从未听说过它。

让我解释一下。

假设我们有一个可观察数组(MyArray),其中每个元素都有"值"可观察。我们希望创建一个计算的可观察量来获得 all 的总和。

显而易见的方法是:

public SommeOne = ko.pureComputed((): number => {
    var res = 0;
    for (var i = 0; i < this.MyArray().length; i++) {
        res += this.MyArray()[i].Value();
    }
    return res;
});

但在这种情况下,对此的呼吁。MyArray() 在每次迭代中被计算两次。和"价值"一次。这对于小数组(少于 1000 个元素)是可以的,但对于较大的数组来说却成了一个问题。所以,到目前为止,我的解决方案是:

public SommeOne = ko.pureComputed((): number => {
    var res = 0;
    var array = this.MyArray();
    for (var i = 0; i < array.length; i++) {
        res += array[i].Value();
    }
    return res;
});

此时,我们只评估一次数组函数(仍然是 1 个 Value 评估,但没关系,我们需要这个),它工作正常。

所以最后一个问题:

如何在不创建中间"阵列"的情况下实施第二个解决方案?

对于一个数组来说很好,但是如果您需要在两个数组之间进行减法,或者更复杂的事情,这很快就会失控。

您几乎肯定会浪费时间担心这些优化。 调用this.myArray()不会进行任何重大计算。 直接从挖空源代码复制,调用可观察数组或可观察数组时执行的逻辑如下:

function observable() {
    if (arguments.length > 0) {
        // Write
        //[Omitted since not relevant here]
    }
    else {
        // Read
        ko.dependencyDetection.registerDependency(observable);
        return _latestValue;
    }
}

除了函数调用的开销和依赖关系检测完成的少量工作(当你不从计算中调用时,它可能基本上只是一个noop函数);可观察函数只是返回对数组或它当前恰好持有的任何对象的引用, 而且对象引用的成本非常低。

数组的长度根本不是一个因素。 它不会"成为更大数组的问题"(至少挖空部分不会;算法的其余部分可能取决于你在做什么),并且你缓存一个已经缓存的值肯定不会是一个重大的性能提升。 (它可能不会使它变得更糟;尽管我认为它对可读性造成了打击,因为它引入了新的变量)

与任何性能问题一样;标准免责声明适用:只有当你首先证明这是代码中需要优化的一个区域,其次,这个淘汰调用是一个重要的性能问题时,你才应该关注这一点。 如果这是您的情况,当然您可以进行一些基准测试,看看缓存值是否会提高您的性能,但根据您对问题的措辞,这里似乎存在更基本的误解。