找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3355|回复: 8

[他山之石] 提高Lisp性能 - cons vs append and foreach vs while/nth对比

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-5-8 17:36:47 | 显示全部楼层 |阅读模式

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

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

×
More and more of you are finding that you have to deal with this goofy language called AutoLISP. Here are a couple items I pulled together related to some lisp “best practices”. Both apply to optimizing performance when processing large “lists” of data.
Thanks,
Nate.

   CONS versus APPEND
The cons function adds an element to the beginning of a list. The append function can be used to give the equivalent of adding an element to the beginning or end of a list.
Using the cons function can be MUCH faster than using append to build up a large list.
We'll run two tests to create a dummy list of 10,000 integer numbers. The first test is using the "cons" function. Appload and type test1 [enter] at the command prompt.
[pcode=lisp,true](defun c:test1 ( / )
   (setq i 1)
   (setq lst nil) ; start out with a blank list
   (repeat 10000
     (setq lst (cons i lst)) ; add next element to beginning of list
     (setq i (1+ i))
   )
   (setq lst (reverse lst)) ; put list back into correct order
   (princ)
)[/pcode]
The second test yields the same result but uses the "append" function:
[pcode=lisp,true](defun c:test2 ( / )
   (setq i 1)
   (setq lst nil) ; start out with a blank list
   (repeat 10000
     (setq lst (append lst (list i))) ; append next element on to end of list
     (setq i (1+ i))
   )
   (princ)
)[/pcode]
The first test using "cons" builds the 10,000 element list in memory in less than 0.01 seconds (on my T61p).The second test using "append" builds the exact same 10,000 element list in memory but takes a full 3.55 seconds to execute ( ! ). Dealing with large lists, it appears that the "cons" function is many, many times faster.
构造10,000元素表,Cons 用时 0.01 , append 用时 3.55
FOREACH versus WHILE / NTH
Let's say you need to cycle through a huge list, one list element at a time. There are two different functions that can cycle through a list, "foreach" and "nth" combined with a "while" loop. When dealing with a very large list, the "foreach" function can be much faster than using a while loop / nth function to index through the list.
These tests use the 10,000 element list held in memory created be either of the above two tests. This next test uses "foreach" to cycle through the 10,000 element list.
[pcode=lisp,true](defun c:test3 ( / )
   ; use 10,000 element "lst" created by test1 or test2
   (setq find_int (getint "\nFind integer="))
   (setq foundit nil)
   (foreach x lst
     (if (AND (not foundit) (= x find_int))
       (progn
         (setq foundit T)
         (princ " found")  
     ) )   
   )
   (princ)
)[/pcode]
This next test does the same thing but uses a "while" loop and the "nth" function to index its way through the 10,000 element list:
[pcode=lisp,true](defun c:test4 ( / )
   ; use 10,000 element "lst" created by test1 or test2
   (setq find_int (getint "\nFind integer="))
   (setq foundit nil)
   (setq ix 0)
   (setq slen (length lst))
   (while (AND (not foundit)(< ix slen))
     (if (= (nth ix lst) find_int) ; look for match
       (progn ; Found the target element
         (setq foundit T)
         (princ " found")  
     ) )
     (setq ix (1+ ix))   
   )
   (princ)
)[/pcode]
For the test, looking for integer value 5000 (halfway into the list). The "foreach" function finds and exits in less than 0.01 second. The while loop using the "nth" function finds and exits in 0.07 seconds. Using foreach is significantly faster in processing this large list.

原文地址: http://www.cppblog.com/85940806/articles/66489.html
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2013-5-8 17:52:27 | 显示全部楼层
从学LISP开始,就知道cons的效率要比append高,当时不知所以然,随着时间的推移,了解的知识多了,这可以从数据结构的角度解释。

LISP的表应该是个单向链表结构,一个元素的尾指针指向下一个元素的头指针,指针就是数据存储的内存地址。

CONS仅仅是把一个元素的尾指针指向一个表的头指针上,一次内存写操作就执行完了。
而由于LISP的单向链表结构,APPEND函数要先遍历所有表元素到达尾部元素的尾指针,才能把它指向要APPEND的元素的头上,如果数据量大的情况下,速度就很慢了。

如果LISP表结构是双向链表的话,效率就是一样的。可惜ADESK公司不是这么设计的LISP表存储结构。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-5-8 18:01:47 | 显示全部楼层
个人理解对 List 处理时如果每个处理不遗漏,While foreach  repeat mapcar 是一样的,看个人喜好,如果中间需要跳出,就加上条件用 while
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-8 18:05:23 | 显示全部楼层

说的对,其实对于现在计算机发展这么迅速的情况下,CPU,内存都不是10多年20多年前可想象的了,代码算法的好坏在普通应用上看不出太大的区别,因为计算机现在运算太快了,内存也太大了。

但是从计算机编程角度来说,研究算法还是具有普遍意义的。既然我们爱好编程,深究下没什么坏处。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2014-11-14 22:00:38 | 显示全部楼层
正需要,谢谢楼主分享
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

发表于 2014-11-14 22:24:29 来自手机 | 显示全部楼层
Car. vs. Last结果怎样?

点评

不用说了,链表结构,CAR最快,除非双链表。  详情 回复 发表于 2014-11-14 22:42
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2014-11-14 22:42:01 | 显示全部楼层

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

使用道具 举报

发表于 2018-5-15 07:40:44 来自手机 | 显示全部楼层
偶然間看到這篇文章,感覺自己在寫lisp的時候忽略了性能方面的問題,有的也該改良一下了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6468个

财富等级: 富甲天下

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 00:24 , Processed in 0.440770 second(s), 49 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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