跳出嵌套循环:return或label/break

Breaking out of nested loops: return or label/break?

本文关键字:label break return 嵌套循环      更新时间:2023-09-26

我使用一个JavaScript函数来设置一个全局变量。下面,我有两个非常愚蠢的示例函数。一种是使用标签跳出嵌套循环。另一个使用空返回。

我的问题:从性能问题来看哪个更好?(为了方便讨论,让我们假设你做了几百万次。)

使用空返回

function foo() {
    for(var i = 0; i < 100; ++i) {
        for(var j = 0; j < 100; ++j) {
            if(i * j == 50) {
                myGlobal = j;
                return;
            }
        }
    }
}

使用标签和打破

function foo() {
    dance:
    for(var i = 0; i < 100; ++i) {
        for(var j = 0; j < 100; ++j) {
            if(i * j == 50) {
                myGlobal = j;
                break dance;
            }
        }
    }
}

我知道在满足内部条件/完成赋值后,除了完成函数,我什么也不做。

谢谢!

经过一些测试(通过Chrome控制台,MBP 2013, OSX 10.9, Intel i7 @ 2.8GHz, 16GB DDR3),结果非常有趣。我做了两种测试第一个测试使用return和label/break跳出嵌套循环。第二个使用了直接的return和label/break,函数中没有其他内容。测试代码:

function r() {
    for(var i = 0; i < 10; ++i) {
        for(var j = 0; j < 10; ++j) {
            if(i*j == 50) {
                return;
            }
        }
    }
}
function b() {
    dance:
    for(var i = 0; i < 10; ++i) {
        for(var j = 0; j < 10; ++j) {
            if(i*j == 50) {
                break dance;
            }
        }
    }
}
function r2() {
    return;
}
function b2() {
    dance:
    break dance;
}
var startTime;
var endTime;
console.log("Return test");
startTime = Date.now();
for(var i = 0; i < 1000000000; ++i) {
    r2();
}
endTime = Date.now();
console.log(endTime - startTime);
console.log("Break test");
startTime = Date.now();
for(var i = 0; i < 1000000000; ++i) {
    b2();
}
endTime = Date.now();
console.log(endTime - startTime);

当比较跳出a和嵌套循环(函数r()和b())时,返回的性能始终明显更好。然而,当在函数(函数r2()和b2())中仅使用return或label/break时,label/break的执行速度明显更快。测试结果分解:

测试1,使用10000000次迭代

使用return离开嵌套循环3次后的平均运行时间(毫秒):1215ms

使用label/break离开嵌套循环运行3次后的平均运行时间(毫秒):1522ms

Test 2,使用1000000000次迭代//2个数量级的迭代

使用return运行3次后的平均运行时间(毫秒):1879ms

使用label/break运行3次后的平均运行时间(毫秒):1862ms

:

对于打破嵌套循环,使用return要快25%

对于科学/高性能计算,使用标签/break快1%

我个人认为,对于一个正常情况下不返回任何内容的函数,使用空返回语句提前中止执行没有什么错。它当然比标签更清晰,而且也更不受语言的影响。许多语言不像你的例子所使用的语言那样支持有标签的for循环,所以对于那些来自其他缺乏该功能的语言的人来说,空返回语句将更容易理解。

两者性能相同;前者可以说更具可读性。但是,如果将来需要在循环之后添加更多指令,后者使修改函数变得更容易。

UPDATE:

好的信息:为什么JavaScript函数总是返回一个值?,第一个答案是:"因此,return和函数执行到它的末端的语义匹配。"所以即使你使用break,在执行结束时它返回的结果和你使用return

一样