将变量设置为现有值与返回值?

时间:2016-06-02 18:24:02

标签: javascript

在Javascript中,我有一个设置变量的函数。如果函数试图将变量设置为当前值,那么打破函数会更“有效”,还是让函数重新设置变量的值?

实施例

var a;
function setStuff(x) {
    if (a == x) { return; }
    a = x;
}

var a;
function setStuff(x) {
    a = x;
}

此功能将在页面滚动时调用,因此将以高频率调用。

5 个答案:

答案 0 :(得分:1)

我不认为问题是“效率”。

然而,我确实认为这里有一种练习,通常不会操纵函数范围之外的值。在你的应用程序中有许多这样的功能会让你疯狂,想知道哪个功能正在改变什么。

而是返回一个新值。

var setStuff = function() {
    return newValue;
}

var a = setStuff();

答案 1 :(得分:1)

我写了一个简单的测试片段:

var a;
function setStuffCheck(x) {
    if (a == x) { return; }
    a = x;
}

function setStuff(x) {
    a = x;
}

function benchmark(func){
    var startTime = Date.now();
    var callCount = 1000000;

    for(var i = 0; i < callCount; i++){
        func(10);
    }

    console.log((Date.now() - startTime) + "ms for "+callCount+" calls setting always the same value");

    startTime = Date.now();
    for(var i = 0; i < callCount; i++){
        func(i);
    }

    console.log((Date.now() - startTime) + "ms for "+callCount+" calls setting always different values");
}

benchmark(setStuffCheck);
benchmark(setStuff);

通过在控制台中复制并粘贴它(Firefox 46.0.1),我有类似的东西:

138ms for 1000000 calls setting always the same value
216ms for 1000000 calls setting always different values
77ms for 1000000 calls setting always the same value
78ms for 1000000 calls setting always different values

所以第二种方式似乎总是更好。但是每台计算机上的结果可能不同。但是,差异仅限于1百万次通话(尝试将其更改为1000,没有差异)。

答案 2 :(得分:0)

第二个选项对我来说更有意义,并且更可行,因为与第一个选项相比,写入的逻辑非常少,因为它检查两个值是否相等,而在第二个选项中它只是重新分配变量为新值。

如果条件总是比仅分配新值时慢。所以我认为你应该选择第二种选择。

答案 3 :(得分:0)

可能有两个因素可能会淹没两个选项之间的任何实际性能差异。在实践中,我建议您使用最容易理解的版本并向其他人解释。我认为这可能是无条件的更新,但它更取决于你。

可能会混淆任何真正差异的两件事是:

  1. 你还在做什么
  2. 分支预测对您的条件有什么影响。
  3. 现在,具体到哪个版本更快的问题。我已经设置了以下测试,每个选项执行了一百万次,每次测试运行10次。全局设置为10次,但您可以通过设置aNew

    将其更改为其他频率

        var a = 10;
        var ittr = 1000 * 1000;
    
        function getRandomIntInclusive(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
    
        function set1(x){
            if (a === x){ return; }
            a = x;
        }
    
        function set2(x){
            a = x;
        }
    
        for (var j = 0; j < 10; j++){
            var start = performance.now();
            for (var i = 0; i< ittr; i++){
                var aNew = a - 10 + getRandomIntInclusive(1,19);
                set1(aNew);
            }
            console.log("conditional : " + (performance.now() - start));
        }
    
        for (var j = 0; j < 10; j++){
            var start = performance.now();
            for (var i = 0; i< ittr; i++){
                var aNew = a - 10 + getRandomIntInclusive(1,19);
                set2(aNew);
            }
            console.log("unconditional : " + (performance.now() - start));
        }

    你的结果可能会有所不同,但我看到有条件的套装()在安定下后平均约为18。无条件的约为17.5。

    请注意,此处的大部分时间都是通过调用random()来完成的。如果你始终只是将全局设置为自身两个函数的时间大约为1.8而不是18,那么建议你在set()中做的其他事情可能会混淆任何性能差异。

答案 4 :(得分:0)

这两者不一定有相同的结果。考虑这一系列的电话:

var a;
function setStuff(x) {
    if (a == x) { return; }
    a = x;
}

setStuffCheck(0) ;
setStuffCheck('0');

console.log(a);

输出不是'0',而是0

为了进行比较,setStuffCheck函数应该使用严格相等运算符===

在我的FireFox测试中,我看到两个功能的性能差别很小。 setStuffCheck当参数的值不同于setStuff时,执行的时间似乎比a略多,但当值相同时,它是相反的(也略有不同)。两种方式的差异大约为2%,这是在典型设备/ PC上因其他原因而无法获得的波动,与代码无关。

无论如何,这也意味着这种轻微的性能差异将取决于您期望使用等于a的参数调用函数的频率。

但是,只有在您进行数亿次通话时才会发现差异。如果您没有那么多电话,那么请不要费心去选择setStuff