gpt4 book ai didi

windows - 为什么 lisp 数到十亿这么慢?

转载 作者:可可西里 更新时间:2023-11-01 12:45:03 24 4
gpt4 key购买 nike

(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> doLisp相当于 while
环形。我对这些有一些疑问 1647s(25+ min) , 我当时在看什么
时间,它可能会减慢执行速度,但差不多 800s ?我不知道。
这些结果令人难以置信。根据Norvig Lisp
Python 快 3 到 85 倍.从我得到的来看,最合乎逻辑的
执行速度如此缓慢的解释是 ClispgclWindows有种
减慢大迭代的错误。怎么样,你问,我不知道?Sooo,我的问题是,为什么这么慢
还有其他人得到类似的东西吗?

更新 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可以拉
跑了不到一分钟。

使用 gcl 运行 Rörd 的代码:

(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 一样快,区别在于关键字 fixnumwith :

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

最佳答案

  • 启动时间
  • 未声明的变量
  • 全局变量
  • 没有类型声明
  • 编译器没有被告知要优化
  • 在 32 位机器/实现上 1000000000 可能不是固定数字,请参阅变量 MOST-POSITIVE-FIXNUM
  • 可能 <与 32 位机器上的 bignum 比较 -> 最好数到 0
  • 实现缓慢

64 位 Common Lisp 应该有更大的 fixnums,我们可以使用简单的 fixnum 计算。

在配备 2 Ghz Intel i7 的 MacBook Air 笔记本电脑上的 64 位 LispWorks 上,我得到未优化的代码,运行时间略低于 2 秒。如果我们添加声明,它会变得更快一些。

(defun billion-test ()
(let ((i 0))
(declare (fixnum i)
(optimize (speed 3) (safety 0) (debug 0))
(inline +))
(loop while (< i 1000000000) do
(setq i (+ i 1)))))


CL-USER 7 > (time (billion-test))
Timing the evaluation of (BILLION-TEST)

User time = 0.973
System time = 0.002
Elapsed time = 0.958
Allocation = 154384 bytes
0 Page faults
NIL

一个 64 位 SBCL 需要 0.3 秒。所以它更快。

使用 GCL,您应该能够在 32 位机器上获得更好的结果。这里我在 32 位 ARM 处理器(三星 Exynos 5410)上使用 GCL。 10 亿是 GCL 在 ARM 机器上仍然是一个 fixnum。

>(type-of 1000000000)

FIXNUM

>(defun billion-test ()
(let ((i 0))
(declare (fixnum i)
(optimize (speed 3) (safety 0) (debug 0))
(inline +))
(loop while (< i 1000000000) do
(setq i (+ i 1)))))

BILLION-TEST

>(compile *)

Compiling /tmp/gazonk_23351_0.lsp.
Warning:
The OPTIMIZE quality DEBUG is unknown.
End of Pass 1.
End of Pass 2.
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3
Finished compiling /tmp/gazonk_23351_0.lsp.
Loading /tmp/gazonk_23351_0.o
start address -T 0x7a36f0 Finished loading /tmp/gazonk_23351_0.o
#<compiled-function BILLION-TEST>
NIL
NIL

现在您可以看到 GCL 也相当快,即使在较慢的 ARM 处理器上也是如此:

>(time (billion-test))

real time : 0.639 secs
run-gbc time : 0.639 secs
child run time : 0.000 secs
gbc time : 0.000 secs
NIL

关于windows - 为什么 lisp 数到十亿这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19252947/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com