highflybird 发表于 2022-7-13 02:13:00

关于lisp内部数据类型vector的小测试

起源于的这个帖子 :
我把vector和list两种数据类型的读取元素的速度进行了比较。
测试代码:
(defun c:ttt()
(setq i 0)
(setq l nil)
(setq n 100000)
(repeat n
    (setq l (cons i l))
    (setq i (1+ i))
)
(setq v (apply 'vector l))
;;最后一个元素
(uti:bench 10000
    (list
      (list 'vector-elt v (1- n))
      (list 'nth (1- n) l)
    )
)
;;第一个元素
(uti:bench 10000
    (list
      (list 'vector-elt v 0)
      (list 'nth 0 l)
    )
)
;;中间元素
(uti:bench 10000
    (list
      (list 'vector-elt v (/ n 2))
      (list 'nth (/ n 2) l)
    )
)
(defun forvector (v / i)
    (setq i 0)
    (repeat (vector-length v)
      (vector-elt v i)
      (setq i (1+ i))
    )
)
(defun forList (lst / i)
    (setq i 0)
    (repeat (length lst)
      (nth i lst)
      (setq i (1+ i))
    )
)

;;平均用时
(uti:bench 10
    (list
      (list 'forvector v)
      (list 'forlist l)
    )
)
   
(princ)
)
测试函数:
(defun UTI:Bench (Times Expressions / s)
(defun Benchmark (Func times / TIME0 TIME1 Speed Value fName)
    (setq fName (car Func))
    (setq TIME0 (getvar "millisecs"))
    (repeat times
      (setq Value (apply fName (cdr func)))
    )
    (setq TIME1 (getvar "millisecs"))
    (setq TIME1 (- TIME1 TIME0 0.0))
    (setq Speed (/ TIME1 times))
    (list fName times TIME1 Speed Value)
)
(BenchCommon Times Expressions)
)在我的笔记本上测试的结果是:
Statement                Times   Elapse(ms)   Average(ms/time)
------------------------------------------------------------------
VECTOR-ELT               10000   468.0          0.0468
NTH                      10000   3063.0         0.3063
Statement                Times   Elapse(ms)   Average(ms/time)
------------------------------------------------------------------
VECTOR-ELT               10000   782.0          0.0782
NTH                      10000   828.0          0.0828
Statement                Times   Elapse(ms)   Average(ms/time)
------------------------------------------------------------------
VECTOR-ELT               10000   829.0          0.0829
NTH                      10000   2062.0         0.2062
Statement                Times   Elapse(ms)   Average(ms/time)
------------------------------------------------------------------
FORVECTOR                10      4547.0         454.7
FORLIST                  10      126953.0       12695.3
读取单个元素的时候,vector优势不是很明显,但平均值优势比较大。
另外vector有一个优点,就是很容易改变某个元素的值或者替换和交换元素,这个是很方便的,对list类型来说,实在不好办。
所以此处我没做比较。
欢迎大家测试。

自贡黄明儒 发表于 2022-7-13 07:18:00

我看过一篇文章,很长很长,只记得说字典也是很神奇的
;;利用字典去重复
(defun C:w1 (/ *DIC*)
(or *dic*
      (setq *dic* (vlax-get-or-create-object "scripting.dictionary"))
)
;;;; Methods supported:
;;;;   Add (2)
;;;;   Exists (1)
;;;;   Items ()
;;;;   Keys ()
;;;;   Remove (1)
;;;;   RemoveAll ()
(vlax-invoke *dic* 'add "a" "a");=>nil
(vlax-invoke *dic* 'add "b" "1")
(vlax-invoke *dic* 'Exists "b");存在=-1,不存在为0

(vlax-invoke *dic* 'Keys);=>("a" "b")
(vlax-invoke *dic* 'Items);=>("a" "1")

(vlax-invoke *dic* 'Remove "a");=>nil
(vlax-invoke *dic* 'Keys);=>("b")
(vlax-invoke *dic* 'RemoveAll);=>nil
(vlax-invoke *dic* 'Keys);nil
)
;;字典去重复
;;(RE '(1 2 3 3 2 1));=>(1 2 3)
(defun RE (lis / A NEW)
(or *dic*
      (setq *dic* (vlax-get-or-create-object "scripting.dictionary"))
)
(while (setq a (car lis))
    (setq lis (cdr lis))
    (if      (= (vlax-invoke *dic* 'Exists a) 0)
      (vlax-invoke *dic* 'add a "")
    )
)
(setq New (vlax-invoke *dic* 'Keys))
(vlax-invoke *dic* 'RemoveAll)
New
)

guosheyang 发表于 2022-7-13 07:51:00

感谢两位大佬的分享!

baitang36 发表于 2022-7-13 08:45:00

有一个保留函数 nth<-可以很方便的替换表中的某个元素。
用法是:(syz-nth<- 序号值表 )
序号和nth的用法一样,从0开始算

小菜123 发表于 2022-7-13 09:18:00

除了点赞,我啥也不会

yyzhan12 发表于 2022-7-13 19:41:00

给高手点赞 + 佩服,给力
页: [1]
查看完整版本: 关于lisp内部数据类型vector的小测试