速度围观,Nodejs代码在try catch 内和外的执行效率相差5倍多

速度围观,Nodejs代码在try catch 内和外的执行效率相差5倍多

虽然用try catch 捕捉next错误很爽,但我们知道不管是try块中的代码还是catch块中的代码,都是无法让V8引擎进行任何优化的,不能优化的函数比优化的函数会慢上好几倍,
也就是说try和catch中的代码比外面的慢很多倍。但是如果是调用try catch块外面的函数就不会有这个问题了。

console.time(1)
try {
    throw new Error()
} catch(e) {
    for (var i = 0; i < 1000000000; i++) {
        var p = i % 2
    }
}
console.timeEnd(1)

// 取出来放在外面
console.time(2)
try {
    throw new Error()
} catch(e) {
    run()
}
console.timeEnd(2)
function run() {
    for (var i = 0; i < 1000000000; i++) {
        var p = i % 2
    }
}

这段代码的的执行结果:

1: 7565ms
2: 1362ms

为何区别这么大呢, 求大神解释


9 回复

速度围观,Node.js代码在try catch 内和外的执行效率相差5倍多

在Node.js中,try...catch 语句对性能的影响是一个值得关注的话题。尽管使用 try...catch 可以方便地捕捉到运行时错误,但它们对性能的影响是显著的。这是因为 V8 引擎在处理 try...catch 块中的代码时无法进行某些优化,从而导致执行速度大幅下降。

示例代码及解释

让我们通过一段简单的代码来展示这种性能差异。

console.time('try-catch-inside');
try {
    throw new Error();
} catch (e) {
    // 在 try-catch 块内执行的代码
    for (let i = 0; i < 1000000000; i++) {
        let p = i % 2;
    }
}
console.timeEnd('try-catch-inside');

console.time('try-catch-outside');
try {
    throw new Error();
} catch (e) {
    // 在 try-catch 块外执行的代码
    run();
}
console.timeEnd('try-catch-outside');

function run() {
    for (let i = 0; i < 1000000000; i++) {
        let p = i % 2;
    }
}

执行结果

假设这段代码在您的环境中执行,输出可能是:

try-catch-inside: 7565ms
try-catch-outside: 1362ms

解释

从上面的代码和结果可以看出,在 try...catch 块内的代码执行时间明显长于块外的代码。原因如下:

  1. 异常处理开销:当代码处于 try...catch 块内时,V8引擎会为该代码段设置异常处理机制。即使没有实际抛出异常,这种机制也会增加额外的开销。

  2. 优化限制:V8引擎在处理 try...catch 块内的代码时,会禁用一些优化策略,例如JIT(Just-In-Time)编译。这会导致代码执行得更慢。

  3. 函数调用优化:将需要频繁执行的代码封装成一个外部函数,并在 try...catch 块外部调用它,可以避免V8引擎对这块代码的优化限制,从而提高性能。

综上所述,虽然 try...catch 提供了一种强大的错误处理机制,但在性能敏感的场景中,应尽可能减少其使用频率,或者将关键代码移至 try...catch 块外。


据说v8优化靠栈缓存,对循环很明显啊

这个问题…所以…我们才约定 …callback(err) 第一个参数为异常…加上nodejs 的异步回调…一般都不用try catch 吧…

忽然想起了一篇文章

http://www.alloyteam.com/2013/12/node-js-series-exception-caught/

试一下用domain 捕获?

domain 也就算一个玩具

把第一段改成这个再试试 =,=

console.time(1)
try {
    throw new Error()
} catch(e) {
	(function(){
		for (var i = 0; i < 1000000000; i++) {
	    	var p = i % 2
		}
	})()
}
console.timeEnd(1)

1: 11999ms 1: 3219ms 闭包

长见识了~还真不知道这个~

在Node.js中,try...catch 语句会对性能产生显著影响,主要原因在于V8引擎对 try...catch 块内的代码进行了特殊处理,导致这些代码无法被V8引擎进行有效的优化。

当代码位于 try...catch 块内时,V8引擎必须考虑可能出现的异常情况,这会导致代码的执行效率降低。相反,如果将可能抛出异常的代码移到 try...catch 块之外,并将其封装在一个单独的函数中,V8引擎可以对这部分代码进行更有效的优化,从而提高执行效率。

以下是改进后的代码示例:

console.time('withTryCatch');
try {
    throw new Error();
} catch(e) {
    for (var i = 0; i < 1000000000; i++) {
        var p = i % 2;
    }
}
console.timeEnd('withTryCatch');

console.time('withoutTryCatch');
try {
    throw new Error();
} catch(e) {
    run();
}
console.timeEnd('withoutTryCatch');

function run() {
    for (var i = 0; i < 1000000000; i++) {
        var p = i % 2;
    }
}

从上面的代码可以看出,将可能抛出异常的代码移到 try...catch 块之外,并将其封装在一个单独的函数中,可以显著提高执行效率。通过这种方式,V8引擎可以更好地优化代码,从而减少执行时间。

回到顶部