看完后隐藏功能和C++/STL的暗角上comp.lang.c++.moderated,我完全惊讶的是,下面的代码片断编译并在两个Visual Studio 2008和G ++ 4.4的工作.
这是代码:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Run Code Online (Sandbox Code Playgroud)
我假设这是C,因为它也适用于GCC.标准中定义了哪里,它来自何处?
我今天在unix中发现了"time"命令,并认为我会用它来检查Haskell中尾递归和正常递归函数之间运行时的差异.
我写了以下函数:
--tail recursive
fac :: (Integral a) => a -> a
fac x = fac' x 1 where
fac' 1 y = y
fac' x y = fac' (x-1) (x*y)
--normal recursive
facSlow :: (Integral a) => a -> a
facSlow 1 = 1
facSlow x = x * facSlow (x-1)
Run Code Online (Sandbox Code Playgroud)
这些都是有效的,记住它们只是用于这个项目,所以我没有费心去检查零或负数.
但是,在为每个编写一个main方法,编译它们,并使用"time"命令运行它们时,两者都具有相似的运行时,正常的递归函数使尾递归函数边缘化.这与我在lisp中关于尾递归优化的内容相反.这是什么原因?
optimization haskell tail-recursion lazy-evaluation tail-call-optimization
我目前正在通过在线学习你的Haskell书籍的方式,并且已经到了一个章节,作者正在解释一些列表连接可能效率低下:例如
((((a ++ b) ++ c) ++ d) ++ e) ++ f
Run Code Online (Sandbox Code Playgroud)
据说效率低下.作者提出的解决方案是使用定义为的"差异列表"
newtype DiffList a = DiffList {getDiffList :: [a] -> [a] }
instance Monoid (DiffList a) where
mempty = DiffList (\xs -> [] ++ xs)
(DiffList f) `mappend` (DiffList g) = DiffList (\xs -> f (g xs))
Run Code Online (Sandbox Code Playgroud)
我很难理解为什么DiffList在某些情况下比简单串联更具计算效率.有人可以用简单的语言向我解释为什么上面的例子是如此低效,以及DiffList以什么方式解决了这个问题?
我有这个代码:
import Data.List
newList_bad lst = foldl' (\acc x -> acc ++ [x*2]) [] lst
newList_good lst = foldl' (\acc x -> x*2 : acc) [] lst
Run Code Online (Sandbox Code Playgroud)
这些函数返回列表,每个元素乘以2:
*Main> newList_bad [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> newList_good [1..10]
[20,18,16,14,12,10,8,6,4,2]
Run Code Online (Sandbox Code Playgroud)
在ghci:
*Main> sum $ newList_bad [1..15000]
225015000
(5.24 secs, 4767099960 bytes)
*Main> sum $ newList_good [1..15000]
225015000
(0.03 secs, 3190716 bytes)
Run Code Online (Sandbox Code Playgroud)
为什么newList_bad功能比它慢200倍newList_good?我知道这不是一个很好的解决方案.但为什么这个无辜的代码工作得如此之慢?
这是什么"4767099960字节"?? 对于那个简单的操作,Haskell使用4 GiB ??
编译后:
C:\1>ghc -O --make test.hs
C:\1>test.exe
225015000
Time for sum (newList_bad [1..15000]) is 4.445889s …Run Code Online (Sandbox Code Playgroud) performance haskell lazy-evaluation strictness weak-head-normal-form
我正在阅读这个 Haskell页面,关于在a的末尾添加一个元素List.
使用这个例子,我为自己试了一下.鉴于以下内容,List我想56在最后添加数字.
例:
let numbers = [4,8,15,16,23,42]
numbers ++ [56]
Run Code Online (Sandbox Code Playgroud)
这条评论让我失望了:
将项添加到列表的末尾是一个很好的练习,但通常你不应该在真正的Haskell程序中这样做.它很昂贵,并表示您正在以错误的顺序构建列表.通常有一种更好的方法.
研究,我意识到我实际上正在做的是创建一个Listwith 56作为唯一的元素,我将它与它结合起来numbers list.那是对的吗?
使用++正确的方法将元素添加到结尾List?