[英]Finding the complexity of Haskell functions
您只能通過查看代碼來計算函數的確切復雜度。 但是,您可以使用標准來估計它。
例如,以下程序將子subsequence
的復雜度估計為列表長度的函數。
module Main where
import Criterion (bench, nf)
import Criterion.Main (defaultMain)
import Data.List (subsequences)
import Control.DeepSeq (deepseq)
main = defaultMain (map createBenchmark [0, 2 .. 24])
where
createBenchmark n =
let
xs = replicate n 'x'
in
xs `deepseq` (bench (show n) $ nf subsequences xs)
如果您編譯它(使用-O2
!)並使用
./Main -u report
(或者
./Main --csv report
在較新版本的標准中)
您將獲得一個 CSV 文件,其中包含數據(每次運行的平均時間、方差和其他信息)。
如果您繪制該數據,您將意識到它是n
的指數,如下面的 gnuplot 會話所示。
> f(x) = a * exp(b * x)
> fit f(x) 'report' using ($0 * 2):2 every ::2 via a,b
...
Final set of parameters Asymptotic Standard Error
======================= ==========================
a = 1.7153e-07 +/- 5.441e-09 (3.172%)
b = 0.711104 +/- 0.001438 (0.2023%)
correlation matrix of the fit parameters:
a b
a 1.000
b -1.000 1.000
> set log y
> set xlabel 'n'
> set ylabel 'mean time [s]'
> plot 'report' using ($0 * 2):2 every ::2 with lp title 'data', f(x) title 'fit'
a
大約為零, b
幾乎沒有錯誤。 所以可以肯定地猜測復雜度是 O(2^n),因為 e^0.71 幾乎正好是 2。
當然,這種技術假定您實際上正在使用函數返回的所有內容。 如果您只訪問返回列表的第一個元素,由於延遲評估,復雜度將為 O(1)。
您可能會找到一種方法使該程序獨立於要進行基准測試的函數(至少對於僅采用列表的函數)。 還有一些不錯的 Haskell 庫用於繪制數據,因此您不需要依賴外部程序(不幸的是,作為一名科學家,我除了 gnuplot 從未使用過任何東西)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.