鱼与熊掌 发表于 2015-6-5 00:56:26

大数据时代.代码不快就崩溃.关于Lisp执行效率探究

本帖最后由 鱼与熊掌 于 2015-6-5 08:34 编辑

Lisp是在Arx托管的代码.那么Lisp的执行效率其实还是蛮低的.
今天一个代码的运行时间本来要1800秒.后来优化了半天优化到了55秒.
其中的差距可想而知,所以探究Lisp的执行效率问题很有必要.
下面是我做的探究.
Vl-remove或者Vl-remove-if-not执行效率高于Repeat
并且Mapcar>Repeat
其他的While更不用说.
总体来说
Vl-remove-if和Vl-remove-if-not的效率高于Mapcar >Repeat .至于While 或者Foreach 没做探究.While肯定比Repeat慢.

下面附上代码



dcl1214 发表于 2025-3-22 00:19:10

再来一个效率研究心得(setq str
       "甲1子2、3乙4丑5 6—7—8 9海0中-金=
丙Q寅W、E丁R卯T Y—U—I O炉P中[火]
\戊A辰S、D己F巳G H—J—K L大Z林X木C
V庚B午N、M辛,未. /—— 路旁土1
2壬3申4、5癸6酉7 8—9—0 -剑=锋A金S
D甲F戌G、H乙J亥K L—Z—X C山V头B火N
M丙,子.、/丁1丑2 3—4—5 6涧7下8水9
0戊-寅=、A己S卯D F—G—H J城K头L土Z
X庚C辰V、B辛N巳M ,—./—1 2白3蜡4金5
6壬7午8、9癸0未- =Q—W—E R杨T柳Y木U
I甲O申P、[乙]\酉A S—D—F G泉H中J水K
L丙Z戌X、C丁V亥B N—M—, .屋上1土2
3戊4子5、6己7丑8 9—0—- =霹Q雳W火E
R庚T寅Y、U辛I卯O P—[—] \松A柏S木D
F壬G辰H、J癸K巳L Z—X—C V长B流N水M
,甲.午/、乙1未2 3—4—5 6沙7中8金9
0丙-申=、丁Q酉W E—R—T Y山U下I火O
P戊[戌]、\A己S亥D F—G—H J平K地L木
庚Z子X、C辛V丑B N—M—, .壁/上1土2
3壬4寅5、6癸7卯8 9—0—- =金Q箔W金E
R甲T辰Y、U乙I巳O P—[—]\ 覆A灯S火D
F丙G午H、J丁K未L —— ZX天C河V水B
N戊M申,、.己/酉1 23—4—5 67大8驿9土0
-庚=戌Q、W辛E亥R T—Y—U I钗O钏P金A
S壬D子F、G癸H丑J K—L—Z X桑C柘V木B
N甲M寅,、.乙/卯1 2—3—4 5大6溪7水8
9丙0辰-=、Q丁W巳E R—T—Y U沙I中O土P
[戊]午]\、A己S未D F—G—H J天K上L火;
'庚ZX申C、V辛B酉N M—,—. /石12榴3木4
5壬6戌7、8癸9亥0 -—=—Q W大E海R水T"
)

(repeat 5 (setq str (strcat str str)))
(strlen str)
(setq TIME0 (getvar "millisecs"))
(repeat500000
(vl-string-position (ascii "/") str)
)
(print
(strcat "vl-string-position耗时:"
    (vl-princ-to-string
      (setq hs (/ (- (getvar "millisecs") TIME0 0.0) 1000.0))
    )
)
)
(setq TIME0 (getvar "millisecs"))
(repeat500000
(wcmatch str "[,*`/*,]")
)
(print
(strcat "wcmatch耗时:"
    (vl-princ-to-string
      (setq hs (/ (- (getvar "millisecs") TIME0 0.0) 1000.0))
    )
)
)




dcl1214 发表于 2025-3-22 00:17:25

我也来一个效率研究心得

(setq TIME0 (getvar "millisecs"))
(SETQ i 0)
(REPEAT50000000
(if (not jb)(progn (setq jb (itoa i)) (setq i (1+ i))))
)
(setq hs (/ (- (getvar "millisecs") TIME0 0.0) 1000.0))
(print(strcat "有not耗时:"(vl-princ-to-string hs)))
;有一个not,执行效率低

(setq TIME0 (getvar "millisecs"))
(SETQ i 0)
(REPEAT50000000
(if jb ()(progn (setq jb (itoa i)) (setq i (1+ i))))
)
(setq hs (/ (- (getvar "millisecs") TIME0 0.0) 1000.0))
(print(strcat "无not耗时:"(vl-princ-to-string hs)))
;没有not,执行效率高,而且编译vlx后,估计不同,有待测试

明_明 发表于 2021-9-29 17:42:22

感谢分享宝贵经验!

鱼与熊掌 发表于 2015-6-5 08:34:44

不好意思.之前上的代码可能有点错误.修正了一下.
总体来说尽量使用Mapcar 或者vl-remove-if-not这样的自带分层函数来优化代码
可以加速非常多.

434939575 发表于 2015-6-5 13:59:04

多谢大侠分享!咱们享受了

鱼与熊掌 发表于 2015-6-5 14:23:12

434939575 发表于 2015-6-5 13:59 static/image/common/back.gif
多谢大侠分享!咱们享受了

发现Foreach和Mapcar一样没什么区别 之前有人说Foreach 执行效率问题..其实应该没有

edata 发表于 2015-6-10 22:14:29

mapcar有个好出,如果批量生成图形,那么需要一个CTRL+Z即可返回,但不确定包含command函数是否可以。

masterlong 发表于 2015-6-10 23:06:58

某些情况下cad环境
对程序的运行也会有重大影响
比如附赠工具中的burst(炸块同时属性转文字)
假设选100个块运行需要0.5秒
选200个块运行需要2秒
选500个块运行需要20秒
选5000个块运行需要30分钟

曾经使出浑身解数也只是改善而不能解决
最终彻底解决所采用的办法是
计数至1000时保存关闭再打开再运行

或许这个例子和楼主所讨论的
属于不同的技术层面
但最终目的是基本一致的
所以适当的情况转换下思路
或许会有意外的收获

鱼与熊掌 发表于 2015-6-10 23:27:51

masterlong 发表于 2015-6-10 23:06 static/image/common/back.gif
某些情况下cad环境
对程序的运行也会有重大影响
比如附赠工具中的burst(炸块同时属性转文字)


这个代码的时间运算量不是线性的优化一下吧.
可以自己写代优化

77077 发表于 2015-6-11 01:02:50

对熊掌的说法略有不同。;计时器开始******************
(defun cx-jsq () ;计时器开始
(setq time_tmp (getvar "TDUSRTIMER"))
)
;计时器结束*****************
(defun cx-end-jsq () ;计时器结束
(setqtime_tmp (- (getvar "TDUSRTIMER") time_tmp)
    ;获得时间,单位小时
    time_tmp (* time_tmp 86400)
) ;秒为单位
(prompt (strcat "用时" (rtos time_tmp 2 4) "秒"))
(setq time_tmp nil)
(princ)
)
;;;准备测试的数据表
(defun c:xx()
(setq all_lst nil)
(setq lst '((0 0 0)(1 1 0)))
(repeat 10000
    (setq all_lst(cons lst all_lst))
)
(princ)
)
;;;repeat
(defun c:xx1()
(setq all_lst1 all_lst)
(setq n (length all_lst1))
(cx-jsq)
(repeat n
    (setq x (car all_lst1))
    (entmake (list '(0 . "line") (cons 10 (car x)) (cons 11 (cadr x))))
    (setq ll_lst1 (cdr ll_lst1))
)
(cx-end-jsq)
(princ)
)
;;;foreach
(defun c:xx2()
(setq all_lst1 all_lst)
(cx-jsq)
(foreach x all_lst1
    (entmake (list '(0 . "line") (cons 10 (car x)) (cons 11 (cadr x))))
)
(cx-end-jsq)
(princ)
)
;;;mapcar
(defun c:xx3()
(setq all_lst1 all_lst)
(cx-jsq)
(mapcar '(lambda (x)
    (entmake (list '(0 . "line") (cons 10 (car x)) (cons 11 (cadr x)))))
    all_lst1
)
(cx-end-jsq)
(princ)
)测试结果很明显和熊掌的不一样~~~~
命令: xx
命令:
命令: xx1
用时0.202秒
命令:
命令: xx2
用时0.221秒
命令:
命令: xx3
用时0.24秒
命令:

77077 发表于 2015-6-11 01:08:15

本帖最后由 77077 于 2015-6-11 01:18 编辑

再增加到10w个测试了一遍,并增加while的比较:;;;while
(defun c:xx4()
(setq all_lst1 all_lst)
(setq n (length all_lst1))
(cx-jsq)
(while (setq x (car all_lst1))
    (entmake (list '(0 . "line") (cons 10 (car x)) (cons 11 (cadr x))))
    (setq all_lst1 (cdr all_lst1))
)
(cx-end-jsq)
(princ)
)命令: xx
命令:
命令: xx1 用时1.904秒
命令:
命令: xx2 用时1.868秒
命令:
命令: xx3 用时1.963秒
命令:
命令: xx4 用时1.849秒
命令:

阿霸jun 发表于 2015-6-11 11:21:57

循环内的代码其实也比较重要,我以前测试的感觉mapcar在数量很大的情况下比较快,跟楼上的不一样,搞不清到底谁快了,一般情况下还是差不多吧,还要考虑代码的易读和易写
页: [1] 2
查看完整版本: 大数据时代.代码不快就崩溃.关于Lisp执行效率探究