高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

例外で処理できるときは例外で処理してしまった方が良い …と思う。

土曜日のわんくま勉強会のけーちゃんのセッションから発展して、プログラムのパフォーマンスの点で話題になってるようです。

nullをif文で避けるか、例外を検出するか それによりプログラムのパフォーマンスにどのような影響を与えるかという話。
パフォーマンスチューニングとか、ローレベルな最適化という観点でいうとわたしにはちょっとうぬぬなのですが・・・。あらためて中さんのコードを見ると、if文でnullを避けようとすると、ブロックが増えてしまうのですよね。
一般にブロックを増やすということは、インデントが増え、行数も増える ――というわけで、ソースの読みやすさが低下してしまう恐れがあります。そう考えるとあまりよろしくないな と。


そもそも例外処理とは、うちにあるたのしいRuby 第2版 Rubyではじめる気軽なプログラミングによると

正常な処理とエラーの処理を分けて記述できるようになり、プログラムの見通しが良くなる

たのしいRuby第2版 152ページ

ためにあるもの。こういうときに例外を使ってコードをすっきりさせるというのは、コードを書く上でもいいことだと思います。try catchで出来ることは素直にtry catchでやってしまった方が楽かな という気がします。


それに・・・

もちろん、マネージドであってもパフォーマンスチューニングは重要です。

ただ、 null チェック( if 文)ひとつのコストを考慮しなきゃいけない場面と云うのはそうあるものじゃないし、そこを考慮する前にやるべき事がたくさんあるだろう、と云うのが私の主張。

プログラムのコストとか - 雑記 - otherwise

とはいえ、状況によって複数の言語を使い分けてる場合、C#のコードと他の言語のコードのアプローチをごっそり変えてしまうのは、あまり好ましくない とわたしは考えてます*1。なのでとりあえず常日頃からパフォーマンスの良いであろうコードを書くように心がけるのはいいことだと思います。



ついでに。ここで思い出された話ですが、DelphiにはEAbortという無視される例外があります。
例え誰もキャッチしなかったとしても例外としてTApplicationクラス(アプリケーションを統括するクラス)に渡って例外として処理されることはなく、単純に全てのメソッドから即時脱出し、GUIに制御を戻すのが標準の動作のものです(CUIでは・・・ どうでしょう。CUIでEAbortを使ってるようなコード見たことないのでわかりませんが)。
そして、ご丁寧にこのEAbortを発生させるだけの、Abortというメソッド(手続き)も用意されていて、わたしもそれなりに使っていたのを覚えています。
例外として処理すべきものをAbortでまとめてしまうのはどうかなー という気はしなくもないですが(そんなにブロックを抜け出したければ、他の例外クラスを使って処理しろよとか)、例外の使い方としてはこういう感じのもので良いんじゃないかなー とか思ったりします。

*1:ブロック例外自体が存在しないような言語ではともかく、C#ならではの例外コード/Rubyならではの例外コード といったものはなるべく作らない方が、言語を使い分けやすくなるとわたしは考えます