淘汰观察和表演

时间:2014-12-27 06:40:01

标签: javascript knockout.js typescript

我现在正在淘汰赛超过1年,但仍有一个问题我无法解决。 这比实际问题更“语法糖”问题。代码简单是在TypeScript中,但它应该没问题,即使你从来没有听说过它。

让我解释一下。

假设我们有一个可观察数组(MyArray),其中每个元素都有“值”可观察。我们想要创建一个计算的observable来获得所有的总和。

明显的方法是:

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

但是在这种情况下,每次迭代都会对this.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;
});

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

所以最后一个问题:

如何在不创建中间“数组”的情况下实施第二种解决方案?

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

1 个答案:

答案 0 :(得分:5)

你几乎肯定会浪费时间来担心这些优化。致电this.myArray()并未进行任何重大计算。直接从knockout source code复制,调用可观察或可观察数组时执行的逻辑如下:

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

除了函数调用的开销和依赖性检测所做的少量工作(当你没有从计算机内调用时,这可能基本上只是一个noop函数); observable函数只返回对数组的引用或者此刻碰巧保持的任何对象,并且对象引用的非常成本很低。

阵列的长度根本不是一个因素。它没有成为更大阵列的问题&#34;,(至少淘汰赛部分没有;算法的其余部分可能取决于你正在做的事情),以及你对缓冲已经缓存的价值的缓存肯定不会成为主要的业绩增长。 (它可能也不会让它变得更糟;虽然我认为它是可读性的一个因素,因为它引入了新的变量)

与任何表演问题一样;标准免责声明适用:如果您首先证明这是需要优化的代码区域,那么您应该只关心这一点,其次,这次淘汰调用是一个重要的性能问题。如果这是您的情况,请确保您可以进行一些基准测试,看看缓存该值是否会改善您的表现,但根据您对问题的处理方式,似乎存在更基本的误解。