Liutos / LiutCL

主动挖坑并打算努力填坑的一个简陋的Lisp解释器
33 stars 4 forks source link

解释器的执行效率亟待提升。 #11

Closed Liutos closed 2 years ago

Liutos commented 2 years ago

用于解决 Project Euler 第三题的代码如下

(defun rec2 (i num)
  (if (or (>= i num)
          (= (mod num i) 0))
      i
      (rec2 (+ i 1) num)))

(defun rec (num acc)
  (cond ((= 1 num) acc)
        ((<= num 2) num)
        (true
         ((lambda (fac)
            (rec (/ num fac) fac))
          (rec2 2 num)))))

(defun largest-prime-factor (n)
  (rec n 1))

(defun main ()
  (print (largest-prime-factor 600851475143)))

在我的设备上,它需要执行五秒钟才能得到结果。

INTERPRETER> (time (with-open-file (s "~/SourceCode/ttt/pro3.lisp")
                 (com.liutos.liutcl.interpreter:load-source-file s)))
6857
Evaluation took:
  5.427 seconds of real time
  5.397333 seconds of total run time (5.330271 user, 0.067062 system)
  [ Run times consist of 0.005 seconds GC time, and 5.393 seconds non-GC time. ]
  99.45% CPU
  11,982,909,202 processor cycles
  76,982,480 bytes consed

#<<VALUE-NUM> 6857>

效率还有非常大的优化空间。

Liutos commented 2 years ago

由于之前用动态作用域的方式实现了函数参数的查找方式,导致效率很差。替换为词法作用域后快多了

INTERPRETER> (time (with-open-file (s "~/SourceCode/ttt/pro3.lisp")
                 (com.liutos.liutcl.interpreter:load-source-file s)))
6857
Evaluation took:
  0.090 seconds of real time
  0.089874 seconds of total run time (0.087894 user, 0.001980 system)
  [ Run times consist of 0.007 seconds GC time, and 0.083 seconds non-GC time. ]
  100.00% CPU
  199,728,408 processor cycles
  76,962,880 bytes consed

#<<VALUE-NUM> 6857>