xugaoming23 发表于 2020-4-21 01:36:23

关于长表中嵌套函数、mapcar和foreach 的效率

本帖最后由 xugaoming23 于 2020-4-21 01:39 编辑

原以为foreach是执行效率最低的,结果不知道怎么回事,在循环8000次时,嵌套函数、mapcar都卡死了,只有foreach存活。

   
(defun XGM:timestart()
    (setq *t1* (getvar "DATE"))
)
(defun XGM:timeend( / s)
    (print (rtos (* 86400.0 (- (setq s (- (getvar "date") *t1*)) (fix s))) 2 2))
)
(setq *tt (getint "请输入循环次数:"))
(defun c:t1 (/ i j lst11 lst22 math:lstcj)
    ;嵌套函数
    (defun math:lstcj(lst1 lst2)
      (if lst2
      (math:lstcj (vl-remove (car lst2) lst1) (cdr lst2))
      lst1
      )   
    )
    (setq i 0 j 5 lst11 nil lst22nil)
    (repeat *tt
      (setq lst11 (cons (setq i (1+ i )) lst11 ))
      (setq lst22 (cons (setq j (1+ j )) lst22 ))
    )
    (XGM:timestart)
    (math:lstcj lst11 lst22)
    (XGM:timeend)
)

(defun c:t2(/ i j lst11 lst22 math:lstcj)
    ;mapcar形式
    (defun math:lstcj(lst1 lst2)
      (mapcar '(lambda (x)(setq lst1 (vl-remove x lst1))) lst2)
      lst1
    )
    (setq i 0 j 5 lst11 nil lst22nil)
    (repeat *tt
      (setq lst11 (cons (setq i (1+ i )) lst11 ))
      (setq lst22 (cons (setq j (1+ j )) lst22 ))
    )
    (XGM:timestart)
    (math:lstcj lst11 lst22)
    (XGM:timeend)
)

(defun c:t3(/ i j lst11 lst22 math:lstcj)
    ;foreach形式
    (defun math:lstcj(lst1 lst2)
      (foreach x lst2 (setq lst1 (vl-remove x lst1)))
    )
    (setq i 0 j 5 lst11 nil lst22nil)
    (repeat *tt
      (setq lst11 (cons (setq i (1+ i )) lst11 ))
      (setq lst22 (cons (setq j (1+ j )) lst22 ))      
    )
    (XGM:timestart)
    (math:lstcj lst11 lst22)
    (XGM:timeend)
)

jun353835273 发表于 2020-4-21 13:12:54

(mapcar '(lambda (x)(setq lst1 (vl-remove x lst1))) lst2)
这一句就会产生一个8000个元素的表,每个元素有8000个元素。一共有6400万个元素。非常可观的数据量
所以mapcar还是要分情况使用。

xugaoming23 发表于 2020-4-22 00:24:46

jun353835273 发表于 2020-4-21 13:12
(mapcar '(lambda (x)(setq lst1 (vl-remove x lst1))) lst2)
这一句就会产生一个8000个元素的表,每个元 ...

明白了,嵌套和mapcar 在内存中会产生很多隐形变量,没有处理完毕时不会回收这些隐形变量,而repeat处理一句及时回收了内存空间,看来简简单单的写程序效率才高,被以往的那些经验欺骗了

jun353835273 发表于 2020-4-22 23:28:49

xugaoming23 发表于 2020-4-22 00:24
明白了,嵌套和mapcar 在内存中会产生很多隐形变量,没有处理完毕时不会回收这些隐形变量,而repeat处理 ...

如果要使用返回后的表,mapcar可以偷懒,直接就得到返回值
用循环还得保存表。没有测试这种情况那种效率高。

xugaoming23 发表于 2020-4-24 00:27:46

jun353835273 发表于 2020-4-22 23:28
如果要使用返回后的表,mapcar可以偷懒,直接就得到返回值
用循环还得保存表。没有测试这种情况那种效率 ...

谢谢解答,大致理解了 mapcar的便捷以及注意情况

tryhi 发表于 2020-4-24 22:18:31

本帖最后由 tryhi 于 2020-4-24 22:52 编辑

你这个就求差集的场景你用mapcar?怕不是在搞笑吧。
可以肯定的跟你讲,mapcar的执行效率至少是foreach的2倍以上
你说的嵌套函数术语叫递归,递归优点是写法简单,很多复杂的算法用递归都非常简便的解决,但是资源开销大,在CAD还有一个2万层的限制,超过2万则奔溃,除非递归用得很娴熟,为了缩短写代码的时间,不然不是很推荐lisp用递归
页: [1]
查看完整版本: 关于长表中嵌套函数、mapcar和foreach 的效率