【问题标题】:break + return vs return Javascript Nodejsbreak + return vs return Javascript Nodejs
【发布时间】:2015-07-15 19:49:14
【问题描述】:

我正在编写一个 nodejs 堆,性能非常重要。我有以下代码:

while(true)
if(x)
 do something
 return
if(y)
 do ...
 return
if(z)
 do ...
else
 return

有人建议我使用

休息

而不是

返回

并在末尾添加一个 return 以避免重复代码并使其更具可读性。是否有性能下降,如果有,有什么影响吗?

换句话说:

仅在循环中使用中断是否有不利之处 在循环之后使用 return 而不是在第一个中使用 return 地点?

【问题讨论】:

  • 不是真正的性能问题,但如果您使用break 而不是return,您可以在while 循环之后粘贴return 并完全删除else,从而制作代码缩短一行。
  • @JamesDonnelly - 对于更糟糕的问题,这是一个糟糕的“答案”(我知道,评论)。正如目前所概述的那样,只要 (!x & !y & z),while 就会继续,删除 else 会使它继续只要 (!x & !y)。但是,无论如何,这不是一个好问题。难以阅读、误导、不清楚,而且可能毫无意义。
  • 代码只是一个例子,我要问的是:在循环中使用中断是否只在循环后使用 return 而不是首先使用 return 有缺点?
  • 这是个坏问题。如果在循环完成后有一些代码要运行怎么办?此外,您那里没有循环。 if -> return else -> return ... while 循环有什么意义?
  • 我猜它在性能方面可能很少。与以往一样,您需要自己在您的环境中进行测量才能确定。另一方面是可读性,但这更多是基于意见的。就个人而言,我更喜欢多次退货。

标签: javascript node.js performance optimization


【解决方案1】:

我能想到的主要区别是在函数内部使用时

function x() {
    var i = 1;
    while (i++) {
        console.log(i);
        if (i == 10) break;
    }
    console.log('outside');
};
x();

break 将退出循环,但return 将退出函数。

【讨论】:

  • 我知道break和return的区别是什么。我纯粹是在性能方面问。
【解决方案2】:

我编写了以下代码来测试这个问题:

// license: public domain
var mode = process.argv[2] === 'break' ? false : true;
var iterations = process.argv[3] ? process.argv[1] : 1e9;
var testIterations = process.argv[4] ? process.argv[2] : 1e4;
var number;
var range = 1e9;

function testA () {
    for (var i = 0; i < testIterations; i++) {
        number = Math.floor(Math.random() * range);
        if (Math.floor(number/2) === number/2) {
            number = number/2;
            return number;
        }
        if (number * number > number + number) {
            number = number * 2;
            return number;
        }
        if (number) {
            number = Math.pow(2, Math.ceil(Math.random()*16));
            return number;
        }
        if (1 === true || 1 == true) {
            number = number - number*number + Math.pow(number, Math.PI);
            return number;
        }
    }
}

function testB () {
    for (var i = 0; i < testIterations; i++) {
        number = Math.floor(Math.random() * range);
        if (Math.floor(number/2) === number/2) {
            number = number/2;
            break;
        }
        if (number * number > number + number) {
            number = number * 2;
            break;
        }
        if (number) {
            number = Math.pow(2, Math.ceil(Math.random()*16));
            break;
        }
        if (1 === true || 1 == true) {
            number = number - number*number + Math.pow(number, Math.PI);
            break;
        }
    }
    return number;
}

console.log('benchmarking ' + (mode ? 'return' : 'break'));
console.time('benchmark');
if (mode) {
    for (var i = 0; i < iterations; i++) {
        var result = testA();
    }
} else {
    for (var i = 0; i < iterations; i++) {
        var result = testB();
    }
}
console.timeEnd('benchmark');

执行后我得到了这些结果(5 个样本):

  1. 基准测试中断:22262ms 基准回报:21947ms

  2. 基准测试中断:22549ms 基准回报:22180ms

  3. 基准测试中断:22443ms 基准回报:22143ms

  4. 基准测试中断:22304ms 基准回报:22109ms

  5. 基准测试中断:22293ms 基准回报:22003ms

总计:中断:111851ms,返回:110382ms,差:1469ms1.3%

如果此基准代码与您的相似,我可以肯定地说,两种变体之间没有显着的性能差异。

【讨论】:

  • 如果性能至关重要并且它们之间没有区别(仅编码风格),即使 1.3% 也可以。谢谢
  • 如果您打算根据该基准更改代码,我建议您再运行几次,因为 1.3% 仍然可能是由于测试或其他因素的随机性。
  • 感谢您的提醒:)。反正改几行也没多大,但我想知道未来,花更长的时间似乎是合乎逻辑的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
相关资源
最近更新 更多