こんにちは、広幡です。
最近Scalaのコードを見ていると、Try(throw new Exception)していたり、Failure(new Exception)していたりと、
人によってバラバラなので揃えたいなーと感じています。
そこで、どっちを扱うほうがいいのか気になったので少し調べてみました。
実行環境
会社支給のMacBook Proで行いました。
| OS | OS X 10.9.5 |
| CPU | 2.3 GHz Intel Core i7 |
| Memory | 16 GB 1600 MHz DDR3 |
| Java | Java8 |
この調査にあたり、sbt-jmhというツールを使っています。 github.com
これについては弊社の記事で書いてありますので、そちらをご参照ください。 labs.septeni.co.jp
結果
いきなりですが、以下が調査結果です。
ソースコードは最後の方に記載しています。
Scoreは単位時間あたりの実行回数が表示されているので、数字が大きいほうが良いです。
ただError(誤差の範囲)が大きいのはご愛嬌。
Benchmark Mode Cnt Score Error Units ExceptionCost.Success型 thrpt 30 143024047.847 ± 3022678.257 ops/s ExceptionCost.Failure型 thrpt 30 914107.851 ± 21209.436 ops/s ExceptionCost.Try型の中でthrow thrpt 30 832233.753 ± 16570.238 ops/s ExceptionCost.例外を握りつぶす thrpt 30 814094.755 ± 14750.842 ops/s
これを見る限り、Success型のやつは高得点を叩きだしてますね。
Failure型パターンとTry型の中でthrowパターンを比べると、Failure型の方が高い得点を出していることがわかります。
もちろん例外を握りつぶすパターンは一番得点が低いですね。
知ってました。このような結果になるのは分かってました。
やはりTryの中でthrowせず、出来る限りFailureで例外を定義したほうがいいという確証が得られました。
まとめ
Try(throw new Exception)ではなくFailure(new Exception)を使え
検証コード
import org.openjdk.jmh.annotations.Benchmark
import scala.util.{Try, Failure, Success}
class ExceptionCost {
@Benchmark
def Success型: Try[Object] = {
Success(new Object)
}
@Benchmark
def Failure型: Try[Object] = {
Failure(new Exception)
}
@Benchmark
def Try型の中でthrow: Try[Object] = {
Try(throw new Exception)
}
@Benchmark
def 例外を握りつぶす: Try[Object] = {
Try(throw new Exception).recover {
case e: Throwable => Success(new Object)
}
}
}