找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 4418|回复: 29

[研讨] mapcar等循环函数优化测试 二期代码

[复制链接]

已领礼包: 3255个

财富等级: 富可敌国

发表于 2013-6-4 16:52:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
本次测试优化了while repeat 和mapcar的算法,测试结果还是不令人满意!

测试数据为:660个边数为1000的多边形,分别用while、repeat、foreach、mapcar,将角点放入一个表中!

while耗时为  4.73秒    repeat 耗时为   4.80秒      foreach 耗时为 90.23秒     mapcar 耗时为 5.53秒

存在两个小问题。

1、用foreach函数怎么过滤掉非角点子表,否则foreach算法方面不如其他函数,以至于测试结果耗时90秒!!!
2、测试是不是要在程序编译的情况下进行呢?我是直接加载代码测试的,不知对否。

  1. ;测试思路:求正多边形的角点,660个边数为1000的多边形,分别用while、repeat、foreach、mapcar,将角点放入一个表中!
  2. ;一、while
  3. (defun c:111( / lst zm) ;test_while
  4.       (setq ss (ssget  '((0 . "LWPOLYLINE"))) i 0 lst nil time1 (get-utime))
  5.       (while (< i (sslength ss))
  6.              (setq zm (entget (ssname ss i)))
  7.              (while (assoc 10 zm)
  8.                     (setq lst (cons (cdr (assoc 10 zm)) lst) zm (cdr (member (assoc 10 zm) zm)));不能用member函数,算法很好,不公平
  9.              )
  10.              (setq i (+ i 1))
  11.       )
  12.       (setq time2 (get-utime) time (strcat "消耗时间为:"(rtos (- time2 time1)) "秒"))
  13. )
  14. ;二、repeat
  15. (defun c:222( / i j lst num ss zm);test_repeat
  16.       (setq ss (ssget  '((0 . "LWPOLYLINE"))) i 0 lst nil num (cdr (assoc 90 (entget (ssname ss 0)))) time1 (get-utime))
  17.       (repeat (sslength ss)
  18.              (setq zm (entget (ssname ss i)) j 0)
  19.              (repeat num
  20.                    (setq lst (cons (cdr (assoc 10 zm)) lst) zm (cdr (member (assoc 10 zm) zm)));不能用member函数,算法很好,不公平
  21.                    (setq j (+ j 1))
  22.              )
  23.              (setq i (+ i 1))
  24.       )
  25.       (setq time2 (get-utime) time (strcat "消耗时间为:"(rtos (- time2 time1)) "秒"))
  26. )
  27. ;三、foreach
  28. (defun c:333( / ent ents i li lst ss zm);test_foreach
  29.       (setq ss (ssget  '((0 . "LWPOLYLINE"))) i 0 lst nil zm nil time1 (get-utime))
  30.       (setq ents (cpf-ss->ents ss))
  31.       (foreach ent ents (if (not zm) (setq zm (entget ent)) (setq zm (append (entget ent) zm))));这里只能用append
  32.       (foreach li zm (if (= (car li) 10) (setq lst (cons (cdr li) lst))))     
  33.       (setq time2 (get-utime) time (strcat "消耗时间为:"(rtos (- time2 time1)) "秒"))
  34. )
  35. ;四、mapcar
  36. (defun c:444( / ents lst ss x zmlst);test_mapcar
  37.       (setq ss (ssget  '((0 . "LWPOLYLINE"))) lst nil zmlst nil time1 (get-utime))
  38.       (setq ents (cpf-ss->ents ss))
  39.       (setq zmlst (apply 'append (mapcar '(lambda(x) (entget x)) ents)))
  40.       (setq lst_10 (vl-remove-if-not '(lambda(x) (= (car x) 10)) zmlst))
  41.       (setq lst (mapcar '(lambda(x) (cdr x)) lst_10))
  42.       (setq time2 (get-utime) time (strcat "消耗时间为:"(rtos (- time2 time1)) "秒"))
  43. )
  44. ;子函数,选择集转化为图元表(通用函数)
  45. (defun cpf-ss->ents(ss / ents i)
  46.       (setq i 0)
  47.       (repeat (sslength ss)
  48.               (setq ents (cons (ssname ss i) ents) i (1+ i))
  49.       )
  50.       ents
  51. )
  52. ;;测试时间函数(通用函数)
  53. (defun get-utime ()
  54.       (* 86400.0 (getvar "tdusrtimer"))
  55. )


评分

参与人数 2D豆 +15 收起 理由
XDSoft + 10 好主题奖!
炫翔 + 5 出题引导交流奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 3255个

财富等级: 富可敌国

 楼主| 发表于 2013-6-4 16:57:29 | 显示全部楼层
附上测试图纸:lol:lol:lol:lol

点评

你的测试图纸呢?  详情 回复 发表于 2013-6-4 17:15
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3255个

财富等级: 富可敌国

 楼主| 发表于 2013-6-4 16:58:38 | 显示全部楼层
:'(:'(:'(:'(:'(:'(为什么我的测试结果,mapcar不如whlie和repeat呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-6-4 17:13:06 来自手机 | 显示全部楼层
写程序不要教条!不要为了mapcar而mapcar,在将选择集转化为表的时候,你就应该把所有的事儿干完了!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 17:15:58 | 显示全部楼层

你的测试图纸呢?

点评

大于1兆 穿不上来  详情 回复 发表于 2013-6-4 18:10
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 17:23:56 | 显示全部楼层
楼主美眉,你的while还可以优化啊

  1. (while (< i (sslength ss))


(sslength ss)是常量,为什么你要在循环条件判断里面都要计算一次? 拿到循环外面去。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 17:27:17 | 显示全部楼层
还是 while 的

  1. (while (assoc 10 zm)


为什么不把 (assoc 10 zm)赋给一个变量,你下面又重复计算了二次(assoc 10 zm)

  1. (setq lst (cons (cdr (assoc 10 zm)) lst) zm (cdr (member (assoc 10 zm) zm)))

1000个实体,你要多重复运算多少次?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 18:01:40 | 显示全部楼层
接下看repeat , 和 while 一样

1、(sslength ss) 赋个变量放到循环外面去
2、 (assoc 10 zm) 重复计算

点评

(repeat num (setq lst (cons (cdr (assoc 10 zm)) lst) zm (cdr (member (assoc 10 zm) zm))) (setq j (+ j 1)) ) 您是说(assoc 10 zm)  详情 回复 发表于 2013-6-4 18:17
明白您的意思了,你能不能回答一下我主题问题啊? 1、用foreach函数怎么过滤掉非角点子表,否则foreach算法方面不如其他函数,以至于测试结果耗时90秒!!! 2、测试是不是要在程序编译的情况下进行呢?我是直接加  详情 回复 发表于 2013-6-4 18:10
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-4 18:07:55 | 显示全部楼层
我不负责测试了,动摇我的信仰{:soso_e120:}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 18:08:18 | 显示全部楼层
接下来看 foreach 的, foreach为啥慢,因为你里面entget的地方用了append, 这个地方没必要用append, 把两个foreach放一个里面,得到entget后,你直接进行第二个foreach里面求顶点的。

你别说什么不公平的问题,你应该在每个代码都是优化的情况下,总体上去和其他的比较效率。而不是另外一个代码有 1+1, 你这个代码就一定有1+1. 能一次循环的就做的,就别分开多次循环。

你用2个FOREACH,本来一个可以做的,你要花2倍的时间。

美眉,看来可能有第三期了。

点评

foreach 对表里面的每一个原子都要判断啊 ,而前面的while和repeat用(assoc 10 xxx)这样的话中间很多其他原子就跳过去了,省去很多判断时间了  详情 回复 发表于 2013-6-4 18:23
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3255个

财富等级: 富可敌国

 楼主| 发表于 2013-6-4 18:10:10 | 显示全部楼层
Lispboy 发表于 2013-6-4 18:01
接下看repeat , 和 while 一样

1、(sslength ss) 赋个变量放到循环外面去

明白您的意思了,你能不能回答一下我主题问题啊?
1、用foreach函数怎么过滤掉非角点子表,否则foreach算法方面不如其他函数,以至于测试结果耗时90秒!!!
2、测试是不是要在程序编译的情况下进行呢?我是直接加载代码测试的,不知对否。

点评

没看到我上面关于foreach的? 没必要编译,你只是在比较相对的速度。环境一样即可。  详情 回复 发表于 2013-6-4 18:15
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3255个

财富等级: 富可敌国

 楼主| 发表于 2013-6-4 18:10:45 | 显示全部楼层
Lispboy 发表于 2013-6-4 17:15
你的测试图纸呢?

大于1兆  穿不上来

点评

就个测试图纸这么大?,PURGE下,然后RAR压缩。传压缩文件。要还是大,RAR分卷压缩,论坛能批量上传多个文件的。  详情 回复 发表于 2013-6-4 18:14
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 18:14:18 | 显示全部楼层
pengfei2010 发表于 2013-6-4 18:10
大于1兆  穿不上来

就个测试图纸这么大?,PURGE下,然后RAR压缩。传压缩文件。要还是大,RAR分卷压缩,论坛能批量上传多个文件的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-6-4 18:15:30 | 显示全部楼层
本帖最后由 Lispboy 于 2013-6-4 18:16 编辑
pengfei2010 发表于 2013-6-4 18:10
明白您的意思了,你能不能回答一下我主题问题啊?
1、用foreach函数怎么过滤掉非角点子表,否则foreach ...

没看到我上面关于foreach的?

没必要编译,你只是在比较相对的速度。环境一样即可。每个函数多运行几次,取个平均时间。测试每次的时间差别也许挺大的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3255个

财富等级: 富可敌国

 楼主| 发表于 2013-6-4 18:17:52 | 显示全部楼层
Lispboy 发表于 2013-6-4 18:01
接下看repeat , 和 while 一样

1、(sslength ss) 赋个变量放到循环外面去

             (repeat num
                   (setq  lst  (cons (cdr (assoc 10 zm)) lst)  zm  (cdr (member (assoc 10 zm) zm)))
                   (setq j (+ j 1))
             )
您是说(assoc 10 zm) 赋个变量放到循环外面去,可是循环里面的zm一直是在变化的啊zm= (cdr (member (assoc 10 zm) zm))
而(sslength ss)是循环次数,程序只需要计算一次吧,怎么会每次都计算这个呢,我做过实验,就是把循环次数设置成一个变化的量,可循环还是按原始第一次的值,所以循环次数变量只计算一次

点评

不是让你放到循环外面啊,是让你在循环里面只计算一次,其他用的地方用变量引用  详情 回复 发表于 2013-6-4 18:25
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-4 09:57 , Processed in 0.191857 second(s), 57 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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