9

GADTの使用を提案して質問に答えると、パフォーマンスに関するいくつかの質問がコメントに表示されました。質問には型クラスが含まれていましたPlotValue

class PlotValue a where
    value :: a -> Double

そして私の答えはGADTを使用することを提案しましたInput

data Input where
    Input :: (PlotValue a, PlotValue b) => Maybe a -> Maybe b -> Input

しかし、詳細は重要ではないと思います。

パフォーマンスの2つの側面について疑問に思っています。

時間:次のようなパターン一致によって発生する実行時コストはありますか

case x of
    Input (Just a) (Just b) -> value a * value b
    _ -> 0.0

Maybe2つの値に一致する通常のコストを超えていますか?

スペース:タイプの値はどのくらいのストレージオーバーヘッドInputを運びますか?私の推測ではPlotValue、タイプのすべての値Input(それぞれ「ポインタ」?)に対して2つの辞書があります。つまり、a[Input]を使用するよりも、メモリ使用量の点ではるかに非効率的(Just Double, Just Double)です(# #Double, #Double #)value通常のタプルまたは解凍されたタプルの結果。

ですから、GADTが私に与える表現力は大好きですが、パフォーマンスの側面についてはあまり考えたことがありません。誰かがこれについてもっと教えてもらえますか(そして私が気付いていないかもしれない他の隠れたコスト)?

4

1 に答える 1

13

私はあなたがオーバーヘッドを釘付けにしたと思います。存在的に修飾された変数ごとに、対応する(ポインタ)ディクショナリが必要です。これにはスペースが必要であり、さらに悪いことに、メソッド呼び出しは遅くなります。この例の(*)は間接的な関数呼び出しになりますが、Doubleでは基本的な操作になります。

于 2011-03-24T23:14:12.750 に答える