Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function 预定义函数与复制源代码的Haskell速度_Function_Haskell - Fatal编程技术网

Function 预定义函数与复制源代码的Haskell速度

Function 预定义函数与复制源代码的Haskell速度,function,haskell,Function,Haskell,为什么当我使用预定义的过滤器时,它的工作速度要比使用一个函数的精确副本快得多 因此,将预定义的过滤器与 filter1 :: (a -> Bool) -> [a] -> [a] filter1 _pred [] = [] filter1 pred (x:xs) | pred x = x : filter1 pred xs | otherwise = filter1 pred xs 当我们这样做的时候 filter2 :: (a -&g

为什么当我使用预定义的
过滤器
时,它的工作速度要比使用一个函数的精确副本快得多

因此,将预定义的
过滤器

filter1 :: (a -> Bool) -> [a] -> [a]
filter1 _pred []    = []
filter1 pred (x:xs)
  | pred x         = x : filter1 pred xs
  | otherwise      = filter1 pred xs
当我们这样做的时候

filter2 ::  (a -> Bool) -> [a] -> [a]
filter2 pred  xs = [x | x <- xs, pred x]
为所有给定值运行
last$filter奇数[1..20000000]

*Main> :set +s

*Main> last $ filter odd [1..20000000]
19999999
(**2.42 secs**, 4,716,736,640 bytes)

*Main> last $ filter1 odd [1..20000000]
19999999
(**15.72 secs**, 6,883,675,064 bytes)

*Main> last $ filter2 odd [1..20000000]
19999999
(**13.17 secs**, 5,839,140,920 bytes)

*Main> last $ filter3 odd [1..20000000]
19999999
(**11.09 secs**, 6,486,331,496 bytes)
为什么
filter1
filter
不同(考虑到
filter1
是源代码),为什么源代码比其他两种实现慢?(使用列表理解或
foldr


注意:最终功能没有任何用途。我刚刚测试了不同的速度…

区别在于,当您直接将
MyFilter.hs
加载到GHCi中时,它会被解释而不是编译

也就是说,使用GHC 7.8.3,通过将所有内容加载到GHCi,以下是我的机器上的计时:

$ ghci-7.8.3 MyFilter.hs
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling MyFilter     ( MyFilter.hs, interpreted )
Ok, modules loaded: MyFilter.
*MyFilter> let xs = [1..20000000] :: [Int]
*MyFilter> :set +s
*MyFilter> last xs  -- Just to remove any effect of evaluating `xs` itself
20000000
(3.00 secs, 627134572 bytes)
*MyFilter> last $ filter odd xs
19999999
(2.00 secs, 1451220660 bytes)
*MyFilter> last $ filter1 odd xs
19999999
(17.55 secs, 2627102272 bytes)
*MyFilter> last $ filter2 odd xs
19999999
(13.54 secs, 1877989348 bytes)
*MyFilter> last $ filter3 odd xs
19999999
(15.44 secs, 2256212504 bytes)
特别注意
MyFilter.hs,解释的

现在,如果我们在将其加载到GHCi之前对其进行编译,则
filter
filter1
/
filter2
/
filter3
之间的时间编号突然对齐:

$ ghc-7.8.3 --make MyFilter.hs
[1 of 1] Compiling MyFilter     ( MyFilter.hs, MyFilter.o )
$ ghci-7.8.3 MyFilter.hs
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: MyFilter.
Prelude MyFilter> let xs = [1..20000000] :: [Int]
Prelude MyFilter> :set +s
Prelude MyFilter> last xs
20000000
(2.84 secs, 710745024 bytes)
Prelude MyFilter> last $ filter odd xs
19999999
(2.07 secs, 1374513668 bytes)
Prelude MyFilter> last $ filter1 odd xs
19999999
(2.07 secs, 1499566524 bytes)
Prelude MyFilter> last $ filter2 odd xs
19999999
(2.12 secs, 1499505652 bytes)
Prelude MyFilter> last $ filter3 odd xs
19999999
(2.26 secs, 1500830732 bytes)

编译代码与解释基本模块包含大量流融合规则。当您运行类似于
last$filter odd[1..20000000]
的程序时,您可能实际上不会得到一个从1到20000000的所有数字的列表,然后遍历该列表以删除偶数,然后遍历到最后一个元素。编译器被允许应用大量的转换,它知道这些转换不会改变结果,但认为可能会更高效的缓存/等等但除此之外。。。正如karafka所说,原因很简单,就是没有对函数进行优化编译。那么,你是如何获得这些时间的呢?@karakfa就是这样吗?我想我认为过滤器也是在解释中解释的,或者只是被解释的加载的.hs?请确保在7.10中签出,至少,
last
被定义为折叠,因此它应该与
过滤器
融合。传递给过滤器的枚举最终是使用
build
定义的,因此它也将与
filter
融合。如果列表库中没有适当的
规则
,所有这些都不会发生。@dfeuer:我们是否仍然同意@matthias看到的最大影响是因为
filter1
/
filter2
/
filter3
被解释了?在GHCi中,这是正确的,因为那里没有发生融合。
$ ghc-7.8.3 --make MyFilter.hs
[1 of 1] Compiling MyFilter     ( MyFilter.hs, MyFilter.o )
$ ghci-7.8.3 MyFilter.hs
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Ok, modules loaded: MyFilter.
Prelude MyFilter> let xs = [1..20000000] :: [Int]
Prelude MyFilter> :set +s
Prelude MyFilter> last xs
20000000
(2.84 secs, 710745024 bytes)
Prelude MyFilter> last $ filter odd xs
19999999
(2.07 secs, 1374513668 bytes)
Prelude MyFilter> last $ filter1 odd xs
19999999
(2.07 secs, 1499566524 bytes)
Prelude MyFilter> last $ filter2 odd xs
19999999
(2.12 secs, 1499505652 bytes)
Prelude MyFilter> last $ filter3 odd xs
19999999
(2.26 secs, 1500830732 bytes)