gpt4 book ai didi

tuples - common-lisp 中有 'tuple' 等价物吗?

转载 作者:行者123 更新时间:2023-12-05 08:58:55 27 4
gpt4 key购买 nike

在我的项目中我有很多坐标要处理,在二维情况下我发现(cons x y)的构造比(list x y)快和 (vector x y)

但是,我不知道如何将 cons 扩展到 3D 或更进一步,因为我没有找到像 cons3 这样的东西。 common-lisp 中的快速 tuple 有什么解决方案吗?

为了说明,我做了以下测试:

* (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

最佳答案

处理此类数据结构的一般方法是使用defstruct。这就是您在 Common Lisp 中创建数据结构的方式。所以,如果你想在三维空间中有一个点,你或多或少会这样做:

(defstruct point-3d x y z)

为什么这比数组更好:

  1. 它正确地命名了事物。

  2. 它创建了一堆您无论如何都会创建的有用的东西,例如访问器、用于测试某些数据是否属于这种类型的函数、用于构造这种类型的对象的函数以及其他一些好东西。

  3. 类型比数组更复杂:您可以分别为每个槽指定类型。

  4. 专门的打印功能,可以很好的打印你的数据。

为什么这比列表更好:

  1. 您始终可以通过执行以下操作来要求结构表现为列表:

(defstruct (point-3d (:type list)) x y z)
  • 所有与数组相同的东西。

优化问题:

您或许应该尝试探索其他替代方案。创建数组或等效内存印记的 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

我的第一个测试版本出现了偏差,因为我忘记在第一次测试之前运行 GC,所以它因不得不回收上一次测试后留下的内存而处于不利地位。现在数字更加精确,并且还表明使用结构和数组之间几乎没有区别。

因此,再次按照我之前的建议:使用对象池、记忆化,以及您可能想到的任何其他优化技术。在这里优化是死路一条。

关于tuples - common-lisp 中有 'tuple' 等价物吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19474602/

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