◆ 1000 倍以上の差があった (devtools 表示時)
◆ デバッグ情報収集してるからか 他と違って try-catch のパフォーマンスは devtools のオンオフで倍くらいの差が出てた

function someProcess(){
    // preProcess
    
    anyProcess(() => {
        if(cond){
            // someProcess の返り値にしたい
            return "message"
        }
    })
    
    // postProcess
    
    return "ok"
}

こんな感じの処理で anyProcess 関数に渡すコールバック関数内の処理で 条件によっては someProcess まで抜けたいということがあります
意味的には例外なので throw して

try{
    anyProcess(() => {
        if(cond){
            // someProcess の返り値にしたい
            throw new Error("message")
        }
    })
}catch(err){
    return err.message
}

こうやって抜ければいいかな と考えてたのですが これくらいなら try-catch を使わずとも


let mesasge
anyProcess(() => {
    if(cond){
        // someProcess の返り値にしたい
        message = "message"
    }
})

if(message){
    return message
}

コレでも十分です
ただ 後から代入される message 変数が必要だったり外側でまた if 文だったりとパッと見てやりたいことが分かりづらい感があります
上の方がスッキリしているのですが try-catch って遅い気もします
けっこう繰り返しの処理なので差が大きいのなら try-catch しない方にしたいです

JavaScript だとそんなに変わらなそうですが try-catch あると実行時コンパイルとか最適化を諦めるケースがあるとかも聞くので計測してみました

計測

1: try-catch
2: if
です

function fn1(){
    try{
        Function.prototype.call.call(() => {
            if(true){
                throw new Error("message")
            }
        })
    }catch(err){
        return err.message
    }
    return true
}

function fn2(){
    let mesasge
    Function.prototype.call.call(() => {
        if(true){
            message = "message"
        }
    })

    if(message){
        return message
    }
    return true
}

function measure1(){
    console.time(1)
    for(let i=0;i<100000;i++) fn1()
    console.timeEnd(1)
}

function measure2(){
    console.time(2)
    for(let i=0;i<100000;i++) fn2()
    console.timeEnd(2)
}

measure1()
measure2()

結果はなんと

1: 4217ms
2: 3ms

1000 倍以上に差がありました
何度か試してもだいたい同じような結果でした
そこまで変わらないかと思ってましたが 違いすぎます

コレくらい単純な try-catch でも 10万回で 4 秒かかっています
要素が 1000 ある配列を 10 パターンの条件でそれぞれ map とかしただけで 1 万回の繰り返しは起きてしまうものです
それらで毎回 try-catch してれば 0.4 秒固まると考えると結構大きいですね

普通エラーなんか起きなそうなところでも念の為と try-catch 書いてる人は時々見ますが バグによるものだと開発中に気づくはずですし必要以上な try-catch を入れるのはやめたほうが良さそうです

devtools

あと スタックトレースとかの都合なのか devtools 無効状態にすると大きく変わりました

だいたい 2200ms で約 2 倍の速度です
他の処理でも devtools を閉じた状態だとパフォーマンスよくなるのもありますがこんなに変わるのはこれくらいじゃないでしょうか
今回の (2) の方の結果は特に違いはありませんでした
devtools を開いてるとエラー時のデバッグ情報が詳しくなるので収集情報も多いはずですから try-catch 周りは影響大きそうですからね

一応閉じた状態で試す方法ですが devtools のコンソールで入力じゃなく手間ですが HTML ファイルにコードを貼り付けてそのファイルを開きます
処理が終わった頃に devtools を開くとコンソールに結果は表示されてる というものです
普段全部コンソールのみでわざわざ HTML ファイル作るようなことしてないのでけっこう面倒なのですよね