Help us understand the problem. What is going on with this article?

rubyでraiseのバックトレースを空にする(ベンチマーク付き)

More than 1 year has passed since last update.

概要

処理をバスッと切ってユーザーにエラーを表示させるようなシチュエーション、例えばAjaxのレスポンスなどで、ロールバックのことなんかも考えるとraiseを使うと便利だと思ったのですが、バックトレースが必要ないので、生成しないようにできたら多少でも軽くなるかなと思って調べてみた。

コード

raise StandardError, 'そんなことしたらあかん!', []

raiseの3番目の引数に空の配列を渡すと生成されないっぽい。

https://docs.ruby-lang.org/ja/2.6.0/method/Kernel/m/raise.html

Catch/Throw

Catch/Throwのことを思い出し試してみた。

ただ、catchの返り値が正常終了時はブロックの返り値、throwするとthrowした値というのが使い勝手が悪かったのと、railsのrescue_fromで処理できないのでアクションごとにごにょごにょ書かいないとダメなのがいまいちだった。

message = catch :error do
  throw :error,'そんなことしたらあかん!'

  # ここで何か処理をするとその返り値がmessageに入り`if message.nil?`がfalseに
end

ベンチマーク

本当にバックトレースが生成されてないのか(かどうかはわからないが早くなってるかどうか)チェックしてみた。

                      user     system      total        real
Backtrace         0.098349   0.001307   0.099656 (  0.099900)
EmptyBacktrace    0.060658   0.000319   0.060977 (  0.061093)
Catch/Throw       0.032181   0.000067   0.032248 (  0.032283)

Backtrace         0.107247   0.001669   0.108916 (  0.109663)
EmptyBacktrace    0.062382   0.000346   0.062728 (  0.063138)
Catch/Throw       0.035800   0.000467   0.036267 (  0.036668)

                      user     system      total        real
Backtrace         0.102345   0.001523   0.103868 (  0.104327)
EmptyBacktrace    0.059909   0.000370   0.060279 (  0.060521)
Catch/Throw       0.032488   0.000130   0.032618 (  0.032768)

3回取ってみた感じはこんな感じ。やっぱりCatch/Throwの方が早いですね。ただ、空バックトレースも一定の効果はありそうです。

参考までにベンチマークのコードはこんな感じ。

require 'benchmark'

count = 100000
Benchmark.bm 15 do |r|
  r.report "Backtrace" do
    count.times do
      begin
        raise StandardError, 'FOOOOOOOOO'
      rescue

      end
    end
  end
  r.report "EmptyBacktrace" do
    count.times do
      begin
        raise StandardError, 'FOOOOOOOOO', []
      rescue

      end
    end
  end
  r.report "Catch/Throw" do
    count.times do
      catch :foo do
        throw :foo, 'FOOOOOOOOO'
      end
    end
  end
end

ベンチマークって平等にやるの意外に難しいですよね。問題に気づいたら教えてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away