Sal*_*Egg 3 tuples common-lisp
在我的项目中,我有很多坐标需要处理,在 2D 情况下,我发现 的构建比和(cons x y)更快。(list x y)(vector x y)
但是,我不知道如何扩展cons到 3D 或更进一步,因为我没有找到类似cons3. tuplecommon-lisp 中有快速的解决方案吗?
为了便于说明,我做了以下测试:
* (time (loop repeat 10000 do (loop repeat 10000 collect (cons (random 10) (random 10)))))
Evaluation took:
7.729 seconds of real time
7.576000 seconds of total run time (7.564000 user, 0.012000 system)
[ Run times consist of 0.068 seconds GC time, and 7.508 seconds non-GC time. ]
98.02% CPU
22,671,859,477 processor cycles
3,200,156,768 bytes consed
NIL
* (time (loop repeat 10000 do (loop repeat 10000 collect (list (random 10) (random 10)))))
Evaluation took:
8.308 seconds of real time
8.096000 seconds of total run time (8.048000 user, 0.048000 system)
[ Run times consist of 0.212 seconds GC time, and 7.884 seconds non-GC time. ]
97.45% CPU
24,372,206,280 processor cycles
4,800,161,712 bytes consed
NIL
* (time (loop repeat 10000 do (loop repeat 10000 collect (vector (random 10) (random 10)))))
Evaluation took:
8.460 seconds of real time
8.172000 seconds of total run time (8.096000 user, 0.076000 system)
[ Run times consist of 0.260 seconds GC time, and 7.912 seconds non-GC time. ]
96.60% CPU
24,815,721,033 processor cycles
4,800,156,944 bytes consed
NIL
Run Code Online (Sandbox Code Playgroud)
小智 6
处理此类数据结构的一般方法是使用defstruct. 这就是在 Common Lisp 中创建数据结构的方式。所以,如果你想在三维空间中有一个点,你或多或少会这样做:
(defstruct point-3d x y z)
Run Code Online (Sandbox Code Playgroud)
为什么这比数组更好:
它正确地命名了事物。
它创建了一堆你无论如何都会创建的有用的东西,例如访问器、测试某些数据是否属于这种类型的函数、构造这种类型的对象的函数以及其他一些好东西。
键入比数组更复杂:您可以单独指定每个槽的类型。
专业的打印功能,可以很好地打印您的数据。
为什么这比列出的更好:
(defstruct (point-3d (:type list)) x y z)
Run Code Online (Sandbox Code Playgroud)
您可能应该尝试探索其他替代方案。创建具有等效内存印记的数组或 cons 单元之间的差异不值得对其进行优化。如果您遇到此特定操作的问题,您应该认为该任务通常难以管理。但我确实认为应该首先尝试对象池、记忆化和通用缓存等技术。
另一个要点:您没有告诉编译器尝试生成有效的代码。您可以告诉编译器优化大小、速度或调试。在指定要尝试进行哪种优化之后,您应该真正测量性能。
我写了一个快速测试来看看有什么区别:
(defstruct point-3d
(x 0 :type fixnum)
(y 0 :type fixnum)
(z 0 :type fixnum))
(defun test-struct ()
(declare (optimize speed))
(loop :repeat 1000000 :do
(make-point-3d :x (random 10) :y (random 10) :y (random 10))))
(time (test-struct))
;; Evaluation took:
;; 0.061 seconds of real time
;; 0.060000 seconds of total run time (0.060000 user, 0.000000 system)
;; 98.36% CPU
;; 133,042,429 processor cycles
;; 47,988,448 bytes consed
(defun test-array ()
(declare (optimize speed))
(loop :repeat 1000000
:for point :of-type (simple-array fixnum (3)) :=
(make-array 3 :element-type 'fixnum) :do
(setf (aref point 0) (random 10)
(aref point 1) (random 10)
(aref point 2) (random 10))))
(time (test-array))
;; Evaluation took:
;; 0.048 seconds of real time
;; 0.047000 seconds of total run time (0.046000 user, 0.001000 system)
;; 97.92% CPU
;; 104,386,166 processor cycles
;; 48,018,992 bytes consed
Run Code Online (Sandbox Code Playgroud)
我的测试的第一个版本出现了偏差,因为我忘记在第一个测试之前运行 GC,因此由于必须回收上一个测试后留下的内存而处于不利地位。现在数字更加精确,并且还表明使用结构体和数组实际上没有区别。
因此,再次按照我之前的建议:使用对象池、记忆化以及您可能想到的任何其他优化技术。在这里优化是死胡同。
| 归档时间: |
|
| 查看次数: |
3121 次 |
| 最近记录: |