簡體   English   中英

找出 Haskell 函數的復雜性

[英]Finding the complexity of Haskell functions

如何找到不同 Haskell 函數的復雜性(就big-O而言)?

例如, subsequences的復雜性是多少?

您只能通過查看代碼來計算函數的確切復雜度。 但是,您可以使用標准來估計它。

例如,以下程序將子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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM