2012-03-13 17 views
3

「動かぬパターンは、パターンData.Maybe.Just bのに失敗しました」I以下の機能を持っている:抑制のランタイムエラーが

PSQがある場合、問題は「ただ」ちょうど空のPSQとして作成されていることを
loopMyQ s q m = forever $ do 
     q' <- atomically $ readTVar q 
     let Just b = PSQ.findMin q' --irrefutable pattern here in case the queue has just been created 
      duetime = (PSQ.prio b) + 2.000 
     now <- getPOSIXTime 
     when (now > duetime) (transMit2 s now q m) 

一致することができず、実行時に反駁できないパターンエラーを返します。明らかにキューは後で埋められ、ジャストbは常に一致するので、これは正確に1回発生します。

私は、キューが空であるかどうかをテストしてから、それを自分の関数で実行しようとしましたが、これですべてが2倍遅くなりました。

これは明らかに傷つきませんので、このエラーは何らかの形で抑止できますか?コンパイラオプションを使用するか、例外をキャッチして無視する必要があります(余分な時間がかかるかもしれません)。

+1

***気になることがありますか***気をつけて***かもしれない余分な時間。正しい、チェックされたコードを書いて、それをプロファイルする。チェックがコードを遅くしている場合は、それを処理します。早期最適化はすべての悪の根源です。 – rampion

+2

私はあなたが失敗したパターンマッチが傷つけることができない方法についてもっと説明する必要があると思います。たとえば、 'loopMyQ'は(別のコメントで述べたように)' forkIO'を使ってスレッド内で開始され、例外がスローされたときにスレッドが消滅しても大丈夫だと言えるでしょう。私は、他のソリューションで見られる減速が、ここで起こっていることよりも他のスレッドがやっていることと関係があるという疑いがあります。 –

+0

@ rampion、benmachineありがとうございます、あなたのコメントは私を正しい道に導きました。プロファイリングを通して、loopMyQの永遠のループは、CPUができるように頻繁に実行され、200msごとにいくつかのアクションを実行したことがわかりました。私にとっては200msごとに実行するだけで十分であり、必要な場合は何らかのアクションを実行することができました。 –

答えて

9

キューが空の場合は、おそらくretry を使用したほうが良いです:TVarでキューが更新されるまでSTMアクションが再試行されません!

loopMyQ s q m = forever $ do 

     b <- atomically $ do q' <- readTVar q 
          case PSQ.findMin q' of 
           Just b -> return b 
           Nothing -> retry 

     let duetime = (PSQ.prio b) + 2.000 
     now <- getPOSIXTime 
     when (now > duetime) (transMit2 s now q m) 
+0

私はこれに似た数々のソリューションを見つけました。すべての実行時間と速度の点で喜び。上記のトリプル実行時間...。 –

+0

@JFritsch "正しい"と "速い"のどちらかの選択肢があるようです。慎重に選択する。 –

+0

@DanielWagner私はまだ誰かが '{ - #DONT print f *ランタイムエラーをターミナル出力として# - ' ' –

5

キューが空でない場合は、再び空にならないと仮定すると、非空になるまで高価なバージョン(空でないことを確認する)を行うだけです。安いバージョン。

loopMyQ s q m = do 
    q' <- atomically $ readTVar q 
    case PSQ.findMin q' of 
     Nothing -> loopMyQ s q m 
     Just b -> do 
     body b 
     forever $ do 
      q' <- atomically $ readTVar q 
      let Just b <- PSQ.findMin q' 
      body b    
    where body b = do 
    let duetime = 2 + PSQ.prio b 
    now <- getPOSIXTime 
    when (now > duetime) (transMit2 s now q m) 
+0

作品 - 実際には、キューが空の状態でさらに多くの条件が発生する可能性があります。 **このようなランタイムエラーを完全に無視する方法はありませんか?例えば。 PatternMatchFailを使って? –

+2

[Control.Exception](http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Exception)を使用して、パターンマッチの失敗などの実行時エラーをキャッチできます。 .html#v%3ADenormal)しかし、この_will_は(実行順序のために)あなたのコードをバグにして、保守しにくく、一元的なものにします。そして、それらのエラーだけを捕まえることができるので、IOモナドに住んでいなければなりません。単純にパターンマッチングを使うのではなく、そのような機械を使うのは間違っています:) – danr

+0

J Fritsch: 'q'に空でないキューだけを保存するように他のコードを変更してみませんか? – rampion