Gu_xl 发表于 2011-11-11 19:05:32

为准确的测试removenth函数的运算速度,我将测试函数的测试规则做了下修改:
表1长20000,分10组取n,均匀分布,分别取1000、3000...19000,不同位置点计算10次
         表2长200,分10组取n,均匀分布,分别取10、30...190,不同位置点计算10次
,这样就考验了removenth函数对长短表的不同位置删除数据的综合能力!
测试函数经过编译后和不经过编译运行,各位的函数计算速度不尽相同!
测试函数:
编译后测试函数:
测试函数未经编译的测试结果:
Gu_xl 方法一:
用时2.03125秒
Gu_xl 方法二:
用时3.42969秒
Gu_xl 方法三:
用时1.32031秒
Gu_xl 方法四repeat:
用时1.23828秒
duotu007 方法:
用时2.29688秒
xshrimp 方法:
用时0.804688秒 (最快)
fsxm 方法:
用时1.07422秒
yjr111 test3方法:
用时2.17969秒
xianaihua递归方法:
用时2.21094秒
xianaihua递归改进方法:
用时1.20703秒
xianaihua迭代方法:
用时0.882813秒
测试函数经编译的测试结果:
Gu_xl 方法一:
用时1.59375秒
Gu_xl 方法二:
用时1.43359秒
Gu_xl 方法三:
用时0.605469秒
Gu_xl 方法四repeat:
用时0.453125秒 (最快)
duotu007 方法:
用时0.839844秒
xshrimp 方法:
用时0.734375秒
fsxm 方法:
用时0.519531秒
yjr111 test3方法:
用时1.03125秒
xianaihua递归方法:
用时0.851563秒
xianaihua递归改进方法:
用时0.539063秒
xianaihua迭代方法:
用时0.863281秒

caoyin 发表于 2011-11-11 19:16:10

我的也是member方法,估计对于超长的表稍快,短表稍慢
(defun LT:LIST-REMOVE-NTH (LST N / X LST2 LE)
(if (setq X (nth N LST))
    (progn
      (setq LST2 (reverse LST)
            LE   (- (length LST) N 1)
      )
      (while (/= (length (setq LST2 (cdr (member X LST2)))) N))
      (while (/= (length (setq LST (cdr (member X LST)))) LE))
      (append (reverse LST2) LST)
    )
)
)

fsxm 发表于 2011-11-11 19:56:41

Gu_xl 测试次数太少啦,
用时都0.几秒
至少达到5s才好些!

Gu_xl 发表于 2011-11-11 20:19:55

本帖最后由 Gu_xl 于 2011-11-11 20:30 编辑

fsxm 发表于 2011-11-11 19:56 http://bbs.mjtd.com/static/image/common/back.gif
Gu_xl 测试次数太少啦,
用时都0.几秒
至少达到5s才好些!

循环100此结果:
未编译测试结果:
Gu_xl 方法一:
用时50.4609秒
Gu_xl 方法二:
用时59.7148秒
Gu_xl 方法三:
用时22.1914秒
Gu_xl 方法四repeat:
用时20.5664秒
duotu007 方法:
用时39.2773秒
xshrimp 方法:
用时9.99219秒
fsxm 方法:
用时18.0234秒
yjr111 test3方法:
用时37.375秒
xianaihua递归方法:
用时39.0898秒
xianaihua递归改进方法:
用时21.0秒
xianaihua迭代方法: (最快)
用时9.71094秒
Caoyin的Member方法:
用时10.0625秒

测试程序编译后测试结果:
Gu_xl 方法一:
用时17.1406秒
Gu_xl 方法二:
用时15.3086秒
Gu_xl 方法三:
用时6.77344秒
Gu_xl 方法四repeat:(最快)
用时5.31641秒
duotu007 方法:
用时9.06641秒
xshrimp 方法:
用时8.48438秒
fsxm 方法:
用时6.0秒
yjr111 test3方法:
用时11.4727秒
xianaihua递归方法:
用时9.08984秒
xianaihua递归改进方法:
用时5.6875秒
xianaihua迭代方法:
用时9.19141秒
Caoyin的Member方法:
用时8.57422秒
******************************
再次测试结果:
编译测试结果:
命令: tt
Gu_xl 方法一:
用时18.0156秒
Gu_xl 方法二:
用时14.8789秒
Gu_xl 方法三:
用时6.26563秒
Gu_xl 方法四repeat:
用时4.75391秒 (还是最快)
duotu007 方法:
用时8.42578秒
xshrimp 方法:
用时7.53125秒
fsxm 方法:
用时5.35156秒
yjr111 test3方法:
用时10.6133秒
xianaihua递归方法:
用时8.66406秒
xianaihua递归改进方法:
用时5.44531秒
xianaihua迭代方法:
用时8.82422秒
Caoyin的Member方法:
用时7.69922秒
命令:
未编译后测试结果:
命令:
命令: tt
Gu_xl 方法一:
用时39.7617秒
Gu_xl 方法二:
用时42.2461秒
Gu_xl 方法三:
用时16.082秒
Gu_xl 方法四repeat:
用时14.9961秒
duotu007 方法:
用时27.7383秒
xshrimp 方法:
用时9.13281秒 (最快)
fsxm 方法:
用时13.0352秒
yjr111 test3方法:
用时26.7266秒
xianaihua递归方法:
用时27.5秒
xianaihua递归改进方法:
用时14.9492秒
xianaihua迭代方法:
用时9.34375秒
Caoyin的Member方法:
用时9.21484秒

fsxm 发表于 2011-11-11 21:33:06

刚测试了编译后,Gu_xl 方法四快些~
Caoyin,xshrimp,的member方法不稳定~,相同元素个数是个问题~
还有member可能只是对数字快些,对string或point类型的表做member可能更慢
递归对小表非常快,表大了会慢,有时还导致堆栈出错

yjr111 发表于 2011-11-11 23:51:57

希望G版、飞版及其他大师们能对此次测试情况进行讲解一下,比如程序的结构或函数等对速度或效率的影响,应该怎样写程序才是正确的。。。我等新手必将获益匪浅!

elitefish 发表于 2011-11-12 12:17:45

对列表 从起始到结束 1/10的表长为步进分别计算5000次

方法1 采用 vl-remove-if 的方法程序简洁速度稳定 idx取中间值时 速度较快
方法2 采用 两头 cdr 再合并的方法 程序简洁 速度稳定   最慢
方法3 采用 GU_XL 的方法4区分前后段计算   速度波动大 两头快 中间慢 平均速度较快
方法4采用递归法同样速度波动大两头快 中间慢 平均速度最快,但递归算法系统开销应该也比较大

测试函数【(EF:LIST-INDEXDEL-1 164 LST)】5000次共耗时:6.50808秒
测试函数【(EF:LIST-INDEXDEL-1 328 LST)】5000次共耗时:8.41916秒
测试函数【(EF:LIST-INDEXDEL-1 493 LST)】5000次共耗时:8.19936秒
测试函数【(EF:LIST-INDEXDEL-1 657 LST)】5000次共耗时:8.18819秒
测试函数【(EF:LIST-INDEXDEL-1 822 LST)】5000次共耗时:8.13603秒
测试函数【(EF:LIST-INDEXDEL-1 986 LST)】5000次共耗时:8.23133秒
测试函数【(EF:LIST-INDEXDEL-1 1150 LST)】5000次共耗时:8.18074秒
测试函数【(EF:LIST-INDEXDEL-1 1315 LST)】5000次共耗时:8.15094秒
测试函数【(EF:LIST-INDEXDEL-1 1479 LST)】5000次共耗时:8.09878秒

测试函数【(EF:LIST-INDEXDEL-2 164 LST)】5000次共耗时:12.7628秒
测试函数【(EF:LIST-INDEXDEL-2 328 LST)】5000次共耗时:12.4983秒
测试函数【(EF:LIST-INDEXDEL-2 493 LST)】5000次共耗时:12.6831秒
测试函数【(EF:LIST-INDEXDEL-2 657 LST)】5000次共耗时:12.7442秒
测试函数【(EF:LIST-INDEXDEL-2 822 LST)】5000次共耗时:13.2024秒
测试函数【(EF:LIST-INDEXDEL-2 986 LST)】5000次共耗时:13.2136秒
测试函数【(EF:LIST-INDEXDEL-2 1150 LST)】5000次共耗时:13.2248秒
测试函数【(EF:LIST-INDEXDEL-2 1315 LST)】5000次共耗时:12.9438秒
测试函数【(EF:LIST-INDEXDEL-2 1479 LST)】5000次共耗时:13.1167秒

测试函数【(EF:LIST-INDEXDEL-3 164 LST)】5000次共耗时:3.02866秒
测试函数【(EF:LIST-INDEXDEL-3 328 LST)】5000次共耗时:5.10365秒
测试函数【(EF:LIST-INDEXDEL-3 493 LST)】5000次共耗时:6.7316秒
测试函数【(EF:LIST-INDEXDEL-3 657 LST)】5000次共耗时:8.55327秒
测试函数【(EF:LIST-INDEXDEL-3 822 LST)】5000次共耗时:10.5053秒
测试函数【(EF:LIST-INDEXDEL-3 986 LST)】5000次共耗时:9.75125秒
测试函数【(EF:LIST-INDEXDEL-3 1150 LST)】5000次共耗时:8.00565秒
测试函数【(EF:LIST-INDEXDEL-3 1315 LST)】5000次共耗时:6.1132秒
测试函数【(EF:LIST-INDEXDEL-3 1479 LST)】5000次共耗时:4.2133秒

测试函数【(EF:LIST-INDEXDEL-递归 164 LST)】5000次共耗时:2.51457秒
测试函数【(EF:LIST-INDEXDEL-递归 328 LST)】5000次共耗时:4.7721秒
测试函数【(EF:LIST-INDEXDEL-递归 493 LST)】5000次共耗时:6.72787秒
测试函数【(EF:LIST-INDEXDEL-递归 657 LST)】5000次共耗时:9.13814秒
测试函数【(EF:LIST-INDEXDEL-递归 822 LST)】5000次共耗时:11.3308秒
测试函数【(EF:LIST-INDEXDEL-递归 986 LST)】5000次共耗时:10.2073秒
测试函数【(EF:LIST-INDEXDEL-递归 1150 LST)】5000次共耗时:8.05035秒
测试函数【(EF:LIST-INDEXDEL-递归 1315 LST)】5000次共耗时:5.8338秒
测试函数【(EF:LIST-INDEXDEL-递归 1479 LST)】5000次共耗时:3.72902秒

elitefish 发表于 2011-11-12 12:21:01

以下为上述结果的 测试程序部分    计算函数 详见上面的附件 Test.lsp;测试函数
(defun C:TT ( / lst i n idxs idx funs fun)
(setq i 5000)                        ;测试次数
(setq lst lst1)        ;测试函数列表
(setq n (length lst))
(setq idxs '(0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9)        ;测试位置
        funs '("EF:List-IndexDel-1"
             "EF:List-IndexDel-2"
             "EF:List-IndexDel-3"
             "EF:List-IndexDel-递归"
             );测试函数名
        )

(princ "\n测试对象 lst 元素共")
(princ n)
(princ "个")

(mapcar '(lambda (fun)
             (mapcar '(lambda (idx)
                        (EF:TimeTest
                          (read (strcat "(" fun " "(rtos (fix (* idx n)) 2 0) " lst)"))
                          i)
                        ) idxs
                     )
             )funs
          )
(princ)
)

;获取当前时间
(defun EF:GetTime (/ Date H M S)
(setq Date (getvar "CDATE"))
(setq H (* (- Date (fix Date)) 100))
(setq M (* (- H (fix H)) 100))
(setq H (fix H))
(setq        S (* (- M (fix M)) 100))
(setq M (fix M))
(+ (* (+ (* H 60) M) 60) S)
)

;函数运行时间测试
(defun EF:TimeTest (fun n / time)
(princ "\n测试函数【")
(princ fun)
(princ "】")
(setq time (EF:GetTime))
(repeat n (eval fun))
(princ (strcat (rtos n 2 0) "次共耗时:"))
(princ (- (EF:GetTime) time))
(princ "秒")
(princ)
)

elitefish 发表于 2011-11-12 15:21:21

补充下 member 方法的测试结果与 递归算法对比

测试对象 lst 元素 共2000个
测试函数(EF:LIST-INDEXDEL-递归 200 LST) 10000次,共耗时:2.75671秒
测试函数(EF:LIST-INDEXDEL-递归 400 LST) 10000次,共耗时:5.10737秒
测试函数(EF:LIST-INDEXDEL-递归 600 LST) 10000次,共耗时:7.47293秒
测试函数(EF:LIST-INDEXDEL-递归 800 LST) 10000次,共耗时:9.84967秒
测试函数(EF:LIST-INDEXDEL-递归 1000 LST) 10000次,共耗时:12.2062秒
测试函数(EF:LIST-INDEXDEL-递归 1200 LST) 10000次,共耗时:12.4276秒
测试函数(EF:LIST-INDEXDEL-递归 1400 LST) 10000次,共耗时:10.0993秒
测试函数(EF:LIST-INDEXDEL-递归 1600 LST) 10000次,共耗时:7.58469秒
测试函数(EF:LIST-INDEXDEL-递归 1800 LST) 10000次,共耗时:5.19305秒

测试函数(REMOVENTH 200 LST) 10000次,共耗时:5.02542秒
测试函数(REMOVENTH 400 LST) 10000次,共耗时:5.15953秒
测试函数(REMOVENTH 600 LST) 10000次,共耗时:5.37404秒
测试函数(REMOVENTH 800 LST) 10000次,共耗时:5.47245秒
测试函数(REMOVENTH 1000 LST) 10000次,共耗时:5.56558秒
测试函数(REMOVENTH 1200 LST) 10000次,共耗时:5.67362秒
测试函数(REMOVENTH 1400 LST) 10000次,共耗时:5.78538秒
测试函数(REMOVENTH 1600 LST) 10000次,共耗时:5.89341秒
测试函数(REMOVENTH 1800 LST) 10000次,共耗时:6.04615秒
从上可以看出 member 的方法 当没有重复项时 速度相当快,但前提是 列表中无重复项
在测试对象为2000个重复项时    速度就非常慢了达到80+s 以上

以下为 递归算法 测试 ,可以看出 递归算法计算时间基本与 列表项数 成正比
测试对象 lst 元素 共1000个
测试函数(EF:LIST-INDEXDEL-递归 500 LST) 1000次,共耗时:0.625849秒

测试对象 lst 元素 共2000个
测试函数(EF:LIST-INDEXDEL-递归 1000 LST) 1000次,共耗时:1.27777秒

测试对象 lst 元素 共3000个
测试函数(EF:LIST-INDEXDEL-递归 1500 LST) 1000次,共耗时:2.64496秒

测试对象 lst 元素 共4000个
测试函数(EF:LIST-INDEXDEL-递归 2000 LST) 1000次,共耗时:4.62309秒

测试对象 lst 元素 共5000个
测试函数(EF:LIST-INDEXDEL-递归 2500 LST) 1000次,共耗时:5.80028秒

测试对象 lst 元素 共6000个
测试函数(EF:LIST-INDEXDEL-递归 3000 LST) 1000次,共耗时:6.94022秒

测试对象 lst 元素 共7000个
测试函数(EF:LIST-INDEXDEL-递归 3500 LST) 1000次,共耗时:8.0727秒

测试对象 lst 元素 共8000个
测试函数(EF:LIST-INDEXDEL-递归 4000 LST) 1000次,共耗时:9.29832秒

测试对象 lst 元素 共9000个
测试函数(EF:LIST-INDEXDEL-递归 4500 LST) 1000次,共耗时:10.4457秒

测试对象 lst 元素 共10000个
测试函数(EF:LIST-INDEXDEL-递归 5000 LST) 1000次,共耗时:11.5766秒

测试对象 lst 元素 共11000个
测试函数(EF:LIST-INDEXDEL-递归 5500 LST) 1000次,共耗时:12.5803秒

测试对象 lst 元素 共12000个
测试函数(EF:LIST-INDEXDEL-递归 6000 LST) 1000次,共耗时:13.9177秒

测试对象 lst 元素 共13000个
测试函数(EF:LIST-INDEXDEL-递归 6500 LST) 1000次,共耗时:14.9161秒

测试对象 lst 元素 共14000个
测试函数(EF:LIST-INDEXDEL-递归 7000 LST) 1000次,共耗时:16.2184秒

测试对象 lst 元素 共15000个
测试函数(EF:LIST-INDEXDEL-递归 7500 LST) 1000次,共耗时:17.3859秒

测试对象 lst 元素 共16000个
测试函数(EF:LIST-INDEXDEL-递归 8000 LST) 1000次,共耗时:18.727秒

测试对象 lst 元素 共17000个
测试函数(EF:LIST-INDEXDEL-递归 8500 LST) 1000次,共耗时:19.5913秒

测试对象 lst 元素 共18000个
测试函数(EF:LIST-INDEXDEL-递归 9000 LST) 1000次,共耗时:20.7297秒

测试对象 lst 元素 共19000个
测试函数(EF:LIST-INDEXDEL-递归 9500 LST) 1000次,共耗时:21.8973秒

测试对象 lst 元素 共20000个
测试函数(EF:LIST-INDEXDEL-递归 10000 LST) 1000次,共耗时:22.9984秒

elitefish 发表于 2011-11-12 15:45:13

再来个 Member 方法的 测试数据
测试 LST为‘( 1 2 3 4 5 6 7 8 9 0 1 2 3 4...)中元素重复率 为10%
从下面测试结果可以看出Member 方法 随 列表元素的数目增加 计算时间是非线形的   时间消耗量 急剧增加
测试对象 lst 元素 共1000个
测试函数(EF:LIST-INDEXDEL-MEMBER 500 LST) 1000次,共耗时:0.566244秒

测试对象 lst 元素 共2000个
测试函数(EF:LIST-INDEXDEL-MEMBER 1000 LST) 1000次,共耗时:1.546秒

测试对象 lst 元素 共3000个
测试函数(EF:LIST-INDEXDEL-MEMBER 1500 LST) 1000次,共耗时:3.06063秒

测试对象 lst 元素 共4000个
测试函数(EF:LIST-INDEXDEL-MEMBER 2000 LST) 1000次,共耗时:5.34579秒

测试对象 lst 元素 共5000个
测试函数(EF:LIST-INDEXDEL-MEMBER 2500 LST) 1000次,共耗时:7.94977秒

测试对象 lst 元素 共6000个
测试函数(EF:LIST-INDEXDEL-MEMBER 3000 LST) 1000次,共耗时:10.8927秒

测试对象 lst 元素 共7000个
测试函数(EF:LIST-INDEXDEL-MEMBER 3500 LST) 1000次,共耗时:14.3498秒

测试对象 lst 元素 共8000个
测试函数(EF:LIST-INDEXDEL-MEMBER 4000 LST) 1000次,共耗时:18.2278秒

测试对象 lst 元素 共9000个
测试函数(EF:LIST-INDEXDEL-MEMBER 4500 LST) 1000次,共耗时:22.4992秒

测试对象 lst 元素 共10000个
测试函数(EF:LIST-INDEXDEL-MEMBER 5000 LST) 1000次,共耗时:27.515秒

测试对象 lst 元素 共11000个
测试函数(EF:LIST-INDEXDEL-MEMBER 5500 LST) 1000次,共耗时:32.7475秒

测试对象 lst 元素 共12000个
测试函数(EF:LIST-INDEXDEL-MEMBER 6000 LST) 1000次,共耗时:38.5344秒

测试对象 lst 元素 共13000个
测试函数(EF:LIST-INDEXDEL-MEMBER 6500 LST) 1000次,共耗时:44.728秒

测试对象 lst 元素 共14000个
测试函数(EF:LIST-INDEXDEL-MEMBER 7000 LST) 1000次,共耗时:51.2845秒

测试对象 lst 元素 共15000个
测试函数(EF:LIST-INDEXDEL-MEMBER 7500 LST) 1000次,共耗时:59.6254秒

测试对象 lst 元素 共16000个
测试函数(EF:LIST-INDEXDEL-MEMBER 8000 LST) 1000次,共耗时:66.5508秒

测试对象 lst 元素 共17000个
测试函数(EF:LIST-INDEXDEL-MEMBER 8500 LST) 1000次,共耗时:74.0758秒

测试对象 lst 元素 共18000个
测试函数(EF:LIST-INDEXDEL-MEMBER 9000 LST) 1000次,共耗时:82.9777秒

测试对象 lst 元素 共19000个
测试函数(EF:LIST-INDEXDEL-MEMBER 9500 LST) 1000次,共耗时:93.0487秒

测试对象 lst 元素 共20000个
测试函数(EF:LIST-INDEXDEL-MEMBER 10000 LST) 1000次,共耗时:104.655秒
页: 1 2 3 [4] 5 6 7
查看完整版本: [讨论]->征求最佳答案:删除表中第 n 个元素的最快算法