(defun billion-test ()
(setq i 0)
(loop while (< i 100) do
(setq i (+ i 1))))
(billion-test)
(print "done")
我有上面的Lisp
代码简单地循环到十亿。问题是它真的很
慢。比我写过的任何琐碎程序都要慢。这些是
使用我拥有的解释器(gcl 和 clisp)运行所需的时间。
Compiled Uncompiled
GNU Common Lisp(gcl) 270-300s 900-960s
Clisp 280-300s 960-1647s
我使用此 Python 代码来计算时间,并使用系统时间
进行Clisp
近似计算,因为您无法从命令提示符运行它。 gcl
import sys
import time
import os
start=time.time()
os.system(" ".join(sys.argv[1:]))
stop=time.time()
print "\n%.4f seconds\n"%(stop-start)
以下是与其他语言的 while 循环的比较:
Kawa scheme 220.3350s
Petite chez 112.827s
C# 1.9130s
Ruby 31.045s
Python 116.8600s 113.7090s(optimized)
C 2.8240s 0.0150s(optimized)
lua 84.6970s
我的假设是这loop while <condition> do
相当于Lisp
一个while
循环。我对此有些怀疑1647s(25+ min)
,当时我正在看一些东西,
它可能会减慢执行速度,但几乎800s
?我不知道。
这些结果令人难以置信。根据Norvig Lisp
的说法,
它的速度是 3 到 85 倍Python
。从我得到的情况来看,对这种缓慢执行最合乎逻辑的解释
是存在某种
会减慢大型迭代的错误。怎么样,你问,我不知道?Sooo,我的问题是,为什么这么慢?有没有其他人得到这样的东西?Clisp
gcl
Windows
更新 1:
我运行了 Joswigs 的程序并得到了这些结果:
compiled uncompiled
gcl 0.8s 12mins
clisp 5mins 18mins
gcl
编译程序很好,clisp
但是给出了这个警告:
;; Compiling file C:\mine\.cl\test.cl ...
WARNING: in BILLION-TEST in lines 1..8 : FIXNUM-SAFETY is not a
valid OPTIMIZE quality.
0 errors, 1 warning
;; Wrote file C:\mine\.cl\test.fas
;; clisp
[2]> (type-of 1000000000)
(INTEGER (16777215))
;;gcl
(type-of 1000000000)
FIXNUM
猜猜这可能是它花了一分钟多的原因。
更新 2:
我想我会再次尝试使用另一种实现,以确认
它确实bignum
是减慢速度的比较。我获得sbcl
了 windows 并再次运行程序:
* (print most-positive-fixnum)
536870911
* (compile-file "count-to-billion.cl")
; compiling file "C:/mine/.cl/count-to-billion.cl"
(written 09 OCT 2013 04:28:24 PM):
; compiling (DEFUN BILLION-TEST ...)
; file: C:/mine/.cl/count-to-billion.cl
; in: DEFUN BILLION-TEST
; (OPTIMIZE (SPEED 3) (SAFETY 0) (DEBUG 0) (FIXNUM-SAFETY 0))
;
; caught WARNING:
; Ignoring unknown optimization quality FIXNUM-SAFETY in:
; (OPTIMIZE (SPEED 3) (SAFETY 0) (DEBUG 0) (FIXNUM-SAFETY 0))
* (load "count-to-billion")
我希望我能告诉你花了多长时间,但我从来没有看到它的结束。等了
2个小时,看了一集吸血鬼日记(呵呵)还没看完。
我原以为它会比Clisp
它更快MOST-POSITIVE-FIXNUM
,嗯,更
积极。我保证实施缓慢,因为只能gcl
完成
不到一分钟的运行。
运行 Rörd 的代码gcl
:
(time (loop with i = 0 while (< i 1000000000) do (incf i)))
gcl with Rords's code:
>(load "count-to-billion.cl")
Loading count-to-billion.cl
real-time : 595.667 secs
run time : 595.667 secs
>(compile-file "count-to-billion.cl")
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3
Finished compiling count-to-billion.cl.
#p"count-to-billion.o"
>(load "count-to-billion")
Loading count-to-billion.o
real time : 575.567 secs
run time : 575.567 secs
start address -T 1020e400 Finished loading count-to-billion.o
48
更新 3:
这是最后一个,我保证。我尝试了 Rords 的其他代码:
(defun billion-test ()
(loop with i fixnum = 0
while (< i 1000000000) do (incf i)))
令人惊讶的是,它的运行速度与 Joswig 一样快,不同之处在于关键字fixnum
和
with
:
gcl
的输出:
real time : 0.850 secs
run time : 0.850 secs
sbcl
的输出(跑了大约半秒然后吐出来):
debugger invoked on a TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {23FC3A39}>:
The value 536870912 is not of type FIXNUM.
clisp
的输出:
Real time: 302.82532 sec.
Run time: 286.35544 sec.
Space: 11798673420 Bytes
GC: 21413, GC time: 64.47521 sec.
NIL