马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 newer 于 2017-6-8 11:09 编辑
今天我们来测试下 repeat,while,mapcar,foreach四个函数的执行效率
对 长度32768的表进行测试
1、 - (defun c:tt1 ()
- (setq lst '(0 1))
- (repeat 14
- (setq lst (append
- lst
- lst
- )
- )
- )
- (defun f-repeat ()
- (setq i 0 len (length lst))
- (repeat len
- (nth i lst)
- (setq i (1+ i))
- )
- )
- (defun f-while ()
- (setq i -1 len (length lst))
- (while (< i len)
- (setq i (1+ i))
- (nth i lst)
- )
- )
- (defun f-foreach ()
- (setq i -1)
- (foreach n lst
- (setq i (1+ i)) ;;元素n直接能用
- )
- )
- (defun f-mapcar ()
- (mapcar
- '(lambda (x)
- (setq i (1+ i)) ;;元素x直接能用
- )
- lst
- )
- )
- (xd::quickbench '(
- (f-repeat)
- (f-while)
- (f-foreach)
- (f-mapcar)
- )
- )
- (princ)
- )
从表中提出每个元素加以利用,上面的代码效率为:
上面结果看到,while,repeat比mapcar,foreach慢接近10倍,那真的是 repeat和while的效率要比 foreach,mapcar慢吗? 我们看,上面循环里面,foreach,mapcar循环是直接就得到元素,而 repeat,while都要通过nth 函数获取对位元素,循环中,每次都要从表头开始去读指定的元素,速度是不是慢在这里了?
下面对repeat,while函数改造下,不用nth函数,而是每次都用car 读取表头元素,同时删除掉表头,这样每次的表头都是对应位置的元素,再看看效率。
 - (defun c:tt3 ()
- (setq lst '(0 1))
- (repeat 14
- (setq lst (append
- lst
- lst
- )
- )
- )
- (defun f-repeat ()
- (setq i -1 len (length lst))
- (repeat len
- (setq a (car lst))
- (setq lst (cdr lst))
- )
- )
- (defun f-while ()
- (setq i -1 len (length lst))
- (while (car lst)
- (setq a (car lst))
- (setq lst (cdr lst))
- )
- )
- (defun f-foreach ()
- (setq i -1)
- (foreach n lst
- (setq a n)
- )
- )
- (defun f-mapcar ()
- (mapcar
- '(lambda (x)
- (setq a x)
- )
- lst
- )
- )
- (xd::quickbench '(
- (f-repeat)
- (f-while)
- (f-foreach)
- (f-mapcar)
- )
- )
- (princ)
- )
测试效率:
这时候验证了我们的猜测,现在4个函数效率基本一个量级了,多次测试,互有胜负。
测试结论:
1、repeat,while不是如以前常说的效率要比foreach,mapcar慢, 快慢决定循环里面是如何读取表数据,尽量用tt3函数里面读数据的方法,尽量别用nth
2、4个函数总体效率差不多,一个级别上,考虑到编程对表处理的方便程度,首选推荐还是mapcar,因为他返回的还是表,能接着做其他函数的参数继续求值。
3、foreach,repeat,while ,这三个,首推foreach ,repeat,while 用哪个无所谓,看自己的习惯。4、4个循环处理函数的特点:while 可以判断条件中间退出,mapcar经过处理也可以判断条件中间退出,另外两个也能,但代码处理要复杂些。
|