Lisp 在球拍中求和非常大的数

Lisp 在球拍中求和非常大的数,lisp,racket,Lisp,Racket,所以我想把0到1亿之间的数字加起来。这段代码对1000万用户非常有效,在我的机器上执行只需3秒钟。然而,当我试图总结到一亿,它冻结了我的电脑,永远没有完成。我已经等待这段代码完成了五分钟,但它仍然没有完成 #lang racket/base (require (only-in racket/list range)) (let ([theList (range 0 100000000)]) (time (apply + theList))) 据我所知,球拍中求和数字的标准方法是使用for/f

所以我想把0到1亿之间的数字加起来。这段代码对1000万用户非常有效,在我的机器上执行只需3秒钟。然而,当我试图总结到一亿,它冻结了我的电脑,永远没有完成。我已经等待这段代码完成了五分钟,但它仍然没有完成

#lang racket/base

(require (only-in racket/list range))

(let ([theList (range 0 100000000)]) (time (apply + theList)))

据我所知,球拍中求和数字的标准方法是使用
for/fold
而不是
apply
,如果你的范围很大:

(for/fold ((n 0))
          ((i (in-range 100000000)))
  (+ n i))

这需要半秒钟才能在我的计算机上运行。

您可以使用
for/sum

(for/sum ([i (in-range 100000000)])
  i)

与所有的
for/xxx
变体一样,
for/sum
基本上是按照
for/fold
实现的(Chris Jester Young对此进行了解释)。换言之,
for/sum
是一个方便的包装器,围绕着
for/fold

,考虑到它将使用的内存量,这并不令人惊讶。我猜你的系统也在寻呼?嗯,我原以为从1000万版到现在,速度只会慢10-15倍。我在Clojure中实现了完全相同的功能,它在我的计算机上只需17秒就可以完成,耗资1亿美元。你对关闭分页有什么建议吗?Clojure懒散地评估这个列表,但Racket没有(至少不是以你写的方式)。对于Racket,您需要更改代码,看看Chris的例子。我不喜欢Racket,但我要阐述我的观点,这可能与x86/x64架构问题有关吗?我将此称为答案,因为它的工作原理与Chris完全相同,但在语法上稍好一些。谢谢你们两个@用户1976901谢谢你接受我的回答。虽然我的更为具体,但克里斯·杰斯特·杨的作品值得一看。如果
for/sum
不存在,您可以使用
for/fold
执行您想要的操作。事实上,你甚至可以为/sum定义一个与Racket提供的表单完全相同的
,这是Racket的诸多优点之一。不客气!如果我没记错的话,for/sum扩展成for/fold。是的,宏是一种乐趣,非常感谢!:)