Lazy Evaluation and Time Complexity

前端 未结 7 584
走了就别回头了
走了就别回头了 2020-12-04 14:05

I was looking around stackoverflow Non-Trivial Lazy Evaluation, which led me to Keegan McAllister\'s presentation: Why learn Haskell. In slide 8, he shows the minimum functi

7条回答
  •  生来不讨喜
    2020-12-04 14:44

    Inspired by Paul Johnson's answer I plotted the growth rates for the two functions. First I modified his code to print one character per comparison:

    import System.Random
    import Debug.Trace
    import Data.List
    import System.Environment
    
    rs n = do
        gen <- newStdGen
        let ns = randoms gen :: [Int]
        return $ take n ns
    
    cmp1 x y = trace "*" $ compare x y
    cmp2 x y = trace "#" $ compare x y
    
    main = do
        n <- fmap (read . (!!0)) getArgs
        xs <- rs n
        print "Sorting entire list"
        print $ sortBy cmp1 xs
    
        print "Head of sorted list"
        print $ head $ sortBy cmp2 xs
    

    Counting the * and # characters we can sample the comparison counts at evenly spaced points (excuse my python):

    import matplotlib.pyplot as plt
    import numpy as np
    import envoy
    
    res = []
    x = range(10,500000,10000)
    for i in x:
        r = envoy.run('./sortCount %i' % i)
        res.append((r.std_err.count('*'), r.std_err.count('#')))
    
    plt.plot(x, map(lambda x:x[0], res), label="sort")
    plt.plot(x, map(lambda x:x[1], res), label="minimum")
    plt.plot(x, x*np.log2(x), label="n*log(n)")
    plt.plot(x, x, label="n")
    plt.legend()
    plt.show()
    

    Running the script would give us the following graph:

    growth rates

    The slope of the lower line is..

    >>> import numpy as np
    >>> np.polyfit(x, map(lambda x:x[1], res), deg=1)
    array([  1.41324057, -17.7512292 ])
    

    ..1.41324057 (assuming it's a linear function)

提交回复
热议问题