こんにちは、広幡です。
最近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) } } }