明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1752|回复: 5

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

[复制链接]
发表于 2020-4-21 01:36:23 | 显示全部楼层 |阅读模式
本帖最后由 xugaoming23 于 2020-4-21 01:39 编辑

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

  1.    
  2.   (defun XGM:timestart(  )
  3.     (setq *t1* (getvar "DATE"))
  4.   )
  5.   (defun XGM:timeend( / s)
  6.     (print (rtos (* 86400.0 (- (setq s (- (getvar "date") *t1*)) (fix s))) 2 2))
  7.   )
  8.   (setq *tt (getint "请输入循环次数:"))
  9.   (defun c:t1 (/ i j lst11 lst22 math:lstcj)
  10.     ;嵌套函数
  11.     (defun math:lstcj(lst1 lst2)
  12.       (if lst2  
  13.         (math:lstcj (vl-remove (car lst2) lst1) (cdr lst2))
  14.         lst1  
  15.       )   
  16.     )  
  17.     (setq i 0 j 5 lst11 nil lst22  nil)
  18.     (repeat *tt
  19.       (setq lst11 (cons (setq i (1+ i )) lst11 ))
  20.       (setq lst22 (cons (setq j (1+ j )) lst22 ))
  21.     )
  22.     (XGM:timestart)
  23.     (math:lstcj lst11 lst22)
  24.     (XGM:timeend)
  25.   )
  26.   
  27.   (defun c:t2(/ i j lst11 lst22 math:lstcj)
  28.     ;mapcar形式
  29.     (defun math:lstcj(lst1 lst2)
  30.       (mapcar '(lambda (x)(setq lst1 (vl-remove x lst1))) lst2)
  31.       lst1
  32.     )
  33.     (setq i 0 j 5 lst11 nil lst22  nil)
  34.     (repeat *tt
  35.       (setq lst11 (cons (setq i (1+ i )) lst11 ))
  36.       (setq lst22 (cons (setq j (1+ j )) lst22 ))
  37.     )
  38.     (XGM:timestart)
  39.     (math:lstcj lst11 lst22)
  40.     (XGM:timeend)
  41.   )
  42.   
  43.   (defun c:t3(/ i j lst11 lst22 math:lstcj)
  44.     ;foreach形式
  45.     (defun math:lstcj(lst1 lst2)
  46.       (foreach x lst2 (setq lst1 (vl-remove x lst1)))
  47.     )
  48.     (setq i 0 j 5 lst11 nil lst22  nil)
  49.     (repeat *tt
  50.       (setq lst11 (cons (setq i (1+ i )) lst11 ))
  51.       (setq lst22 (cons (setq j (1+ j )) lst22 ))      
  52.     )
  53.     (XGM:timestart)
  54.     (math:lstcj lst11 lst22)
  55.     (XGM:timeend)
  56.   )  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2020-4-21 13:12:54 | 显示全部楼层
(mapcar '(lambda (x)(setq lst1 (vl-remove x lst1))) lst2)
这一句就会产生一个8000个元素的表,每个元素有8000个元素。一共有6400万个元素。非常可观的数据量
所以mapcar还是要分情况使用。
 楼主| 发表于 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处理一句及时回收了内存空间,看来简简单单的写程序效率才高,被以往的那些经验欺骗了
发表于 2020-4-22 23:28:49 | 显示全部楼层
xugaoming23 发表于 2020-4-22 00:24
明白了,嵌套和mapcar 在内存中会产生很多隐形变量,没有处理完毕时不会回收这些隐形变量,而repeat处理 ...

如果要使用返回后的表,mapcar可以偷懒,直接就得到返回值
用循环还得保存表。没有测试这种情况那种效率高。
 楼主| 发表于 2020-4-24 00:27:46 | 显示全部楼层
jun353835273 发表于 2020-4-22 23:28
如果要使用返回后的表,mapcar可以偷懒,直接就得到返回值
用循环还得保存表。没有测试这种情况那种效率 ...

谢谢解答,大致理解了 mapcar的便捷以及注意情况
发表于 2020-4-24 22:18:31 | 显示全部楼层
本帖最后由 tryhi 于 2020-4-24 22:52 编辑

你这个就求差集的场景你用mapcar?怕不是在搞笑吧。
可以肯定的跟你讲,mapcar的执行效率至少是foreach的2倍以上
你说的嵌套函数术语叫递归,递归优点是写法简单,很多复杂的算法用递归都非常简便的解决,但是资源开销大,在CAD还有一个2万层的限制,超过2万则奔溃,除非递归用得很娴熟,为了缩短写代码的时间,不然不是很推荐lisp用递归
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-18 05:22 , Processed in 0.172553 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表