找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1930|回复: 7

[研讨] 三种等分表的函数效率测试

[复制链接]

已领礼包: 24个

财富等级: 恭喜发财

发表于 2007-2-10 10:52:03 | 显示全部楼层 |阅读模式

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

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

×
近来编程需要做大量的等分表操作,于是比较了以下三个函数,供大家参考:
第一个函数摘录于std程序包
[pcode=lisp,true]
;;; STD-SPLIT-LIST splits list into sublists of maximal length n
;;; n must be > 0!
;;; Iterative version by Serge Pashkov, safer than recursive version
;;;   (std-split-list 2 '(1 2 3 4 5 6)) => ((1 2) (3 4) (5 6))
(defun STD-SPLIT-LIST (n lst / ret out cnt)
  (setq ret nil)        ; possible VL lsa compiler bug
  ;; adjust cnt to set incomplete number of elements (if any) for the
  ;; last segment
  (setq cnt (- n (rem (length lst) n)) lst (reverse lst))
  (while lst
    (setq ret (cons (car lst) ret) lst (cdr lst))
    (if (zerop (rem (setq cnt (1+ cnt)) n))
      (setq out (cons ret out) ret nil)))
  (if ret (cons ret out) out))
[/pcode]

第二个函数是本论坛函数库收集提供的
;;http://www.xdcad.net/forum/showthread.php?s=&threadid=451886

[pcode=lisp,true]

;;       a-->(1 2 3 4 5 6 7 8)
;;       (split 2 a)-->((1 2) (3 4) (5 6) (7 8))
;;       (split 3 a)-->((1 2 3) (4 5 6) (7 8))
;;By Aeo
(defun lst-split(n li /  return a len)
(while li
   (setq a   nil
         len(length li)
   )
   (repeat (if(<= n len)n len)
      (setq a(cons (car li)a) li(cdr li))
   )
   (setq return(cons(reverse a)return))
)
(reverse return)
)
[/pcode]

第三个函数是明经通道ALISP函数库收集提供的

[pcode=lisp,true]

;;http://www.mjtd.com/Functions/ArticleShow.asp?ArticleID=1004
;|(xl_div lst nom)表分段. -> 返回 分段的表.   ------by 无痕.2004.1
; lst = 表,nom = 分段的子表元素个数(从1开始计).
; 测试: (xl_div '(1 2 3 4 5 6 7 8 9) 3) -> ((1 2 3) (4 5 6) (7 8 9))
         (xl_div '(1 2 3 4 5 6 7 8 9 10 11) 3) -> ((1 2 3) (4 5 6) (7 8 9) (10 11))
         (xl_div '(17086.8 5666.8 0.0 16093.0 8693.12 0.0 16093.0 7827.36 0.0 16093.0 6639.13 0.0) 3)
         -> ((17086.8 5666.8 0.0) (16093.0 8693.12 0.0) (16093.0 7827.36 0.0) (16093.0 6639.13 0.0))
         (xl_div nil 2) -> nil
|;
;;方法7. ok!**************************************************
(defun xl-div (lst x / lst2)
   (foreach n lst
     (if (and  lst2 (/= x (length (car lst2))))   
  (setq lst2 (cons (append (car lst2)(list n))(cdr lst2)))
  (setq lst2 (cons (list n) lst2))
     )
   )(reverse lst2)
)
[/pcode]
测试数据准备
[pcode=lisp,true]
;;等份单元为length 4
(setq a 4)
(SETQ b        '(17086.8 5666.8 0.0 16093.0 8693.12 0.0 16093.0 -236290.0 94625.0 7827.36))
;;典型的PLINE点表
(SETQ c        '((10 -236290.0 94625.0) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -314670.0 24235.5) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -285278.0 13047.7) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -247487.0 43347.9) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -231625.0 11649.3) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -210630.0 11649.3) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -200833.0 -3267.72) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -237223.0 -14921.6) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -266149.0 -1869.25) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
          (10 -301607.0 -18184.7) (40 . 0.0) (41 . 0.0)  (42 . 0.0)
         )
)
(setq d c)
; length 1280 长表
(repeat 5 (setq d (append d d)))
[/pcode]
测试结果
[pcode=lisp,true]
(benchmark '((STD-SPLIT-LIST a b) (lst-split a b) (xl-div b a)))
Benchmarking ................Elapsed milliseconds / relative speed for 8192 iteration(s):

    (STD-SPLIT-LIST A B).....1516 / 1.2 <fastest>
    (LST-SPLIT A B)..........1688 / 1.07
    (XL-DIV B A).............1812 / 1 <slowest>

(benchmark '((STD-SPLIT-LIST a c) (lst-split a c) (xl-div c a)))
Benchmarking ...............Elapsed milliseconds / relative speed for 4096 iteration(s):

    (STD-SPLIT-LIST A C).....1140 / 1.49 <fastest>
    (LST-SPLIT A C)..........1437 / 1.19
    (XL-DIV C A).............1703 / 1 <slowest>

(benchmark '((STD-SPLIT-LIST a d) (lst-split a d) (xl-div d a)))
Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s):

    (STD-SPLIT-LIST A D).....1344 / 2.06 <fastest>
    (XL-DIV D A).............2406 / 1.15
    (LST-SPLIT A D)..........2766 / 1 <slowest>
[/pcode]

结论:
1.推荐使用第一个函数,效率较高.
2.后两个函数因为频繁调用length,表项越多,效率越低,表项1300时,执行速度和第一个函数已经相差接近1倍.

本贴仅为测试函数,请Aeo和无痕不要介意.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2008-3-30 22:19:38 | 显示全部楼层
关于列表分段,我自己也写过很多个版本,你可试试下面的这个版本。----------无痕


  1.   [FONT=courier new]
  2. ;| (xl-div n lst) = 表分段----------by lxx.
  3. 测试:(xl-div 2 '(1 2 3 4 5 6 7)) -> ((1 2) (3 4) (5 6) (7))
  4. |;
  5. (defun xl-div (n lst / A I LL)
  6.   (setq i 1)
  7.   (mapcar '(lambda (x)
  8.              (if (< i n)
  9.                (setq a (cons x a)
  10.                      i (1+ i))
  11.                (setq ll (cons (reverse (cons x a)) ll)
  12.                      a nil
  13.                      i 1)
  14.                
  15.               )
  16.            )
  17.           lst
  18.   )
  19.   (reverse (if a (cons (reverse a) ll) ll))
  20. )
  21.   [/FONT]


  1.   [FONT=courier new]
  2. _$ (c:test)
  3. Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

  4.     (XL-DIV A B).............1406 / 1.09 <fastest>
  5.     (STD-SPLIT-LIST A B).....1422 / 1.08
  6.     (LST-SPLIT A B)..........1531 / 1.00 <slowest>
  7. Benchmarking ................Elapsed milliseconds / relative speed for 8192 iteration(s):

  8.     (XL-DIV A C).............1172 / 1.32 <fastest>
  9.     (STD-SPLIT-LIST A C).....1359 / 1.14
  10.     (LST-SPLIT A C)..........1547 / 1.00 <slowest>
  11. Benchmarking .......Elapsed milliseconds / relative speed for 16 iteration(s):

  12.     (XL-DIV A D)..............1578 / 15.98 <fastest>
  13.     (STD-SPLIT-LIST A D)......1875 / 13.45
  14.     (LST-SPLIT A D)..........25219 / 1.00 <slowest>  [/FONT]
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2008-6-7 13:48:54 | 显示全部楼层

  1.   [FONT=courier new]
  2. ;;; 经测试,以下的最快.
  3. (defun hao-lst-split (lst n)
  4.   (if lst
  5.     (cons (th-del-lst>mn< 0 (1- n) lst) (hao-lst-split
  6.                                                        (th-del-lst>mn< n
  7.                                                                        (length lst)
  8.                                                                        lst
  9.                                                        ) n
  10.                                         )
  11.     )
  12.   )
  13. )
  14. (defun th-del-lst>mn< (m n lst / j)    ; 保留列表的第m~n项
  15.   (setq j -1)
  16.   (vl-remove-if-not '(lambda (x)
  17.                        (and
  18.                          (setq j (1+ j))
  19.                          (<= m j)
  20.                          (>= n j)
  21.                        )
  22.                      ) lst
  23.   )
  24. )

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

使用道具 举报

发表于 2008-6-8 23:08:36 | 显示全部楼层
用 vl-remove-* 还能最快,说什么也不相信。据我的经验,这个函数的效率并不算高。
你自己先用测试函数测试一下贴出来。
这是我测试的结果
Elapsed milliseconds / relative speed for 8192 iteration(s):
    (XL-DIV A B).............1265 / 7.82 <fastest>
    (STD-SPLIT-LIST A B).....1281 / 7.72
    (HAO-LST-SPLIT B A)......9890 / 1.00 <slowest>

Elapsed milliseconds / relative speed for 4096 iteration(s):
    (XL-DIV A C)..............1000 / 17.75 <fastest>
    (STD-SPLIT-LIST A C)......1141 / 15.56
    (HAO-LST-SPLIT C A)......17750 / 1.00 <slowest>

Elapsed milliseconds / relative speed for 512 iteration(s):
    (XL-DIV A D)...............1968 / 221.50 <fastest>
    (STD-SPLIT-LIST A D).......2547 / 171.15
    (HAO-LST-SPLIT D A)......435921 / 1.00 <slowest>

附上测试函数

  1. (defun Benchmark
  2.                  ;;=================================================================  
  3.                  ;;  
  4.                  ;;  Benchmark.lsp | ?? 2005 Michael Puckett | All Rights Reserved  
  5.                  ;;  
  6.                  ;;=================================================================  
  7.                  ;;  
  8.                  ;;  Purpose:  
  9.                  ;;  
  10.                  ;;      Compare the performance of various statements.  
  11.                  ;;  
  12.                  ;;  Notes:  
  13.                  ;;  
  14.                  ;;      I make no claims that this is definitive benchmarking. I  
  15.                  ;;      wrote this utility for my own purposes and thought I'd  
  16.                  ;;      share it. Many considerations go into evaluating the  
  17.                  ;;      performance or suitability of an algorythm for a given  
  18.                  ;;      task. Raw performance as profiled herein is just one.  
  19.                  ;;  
  20.                  ;;      Please note that background dramatically affect results.  
  21.                  ;;  
  22.                  ;;  Disclaimer:  
  23.                  ;;  
  24.                  ;;      This program is flawed in one or more ways and is not fit  
  25.                  ;;      for any particular purpose, stated or implied. Use at your  
  26.                  ;;      own risk.  
  27.                  ;;  
  28.                  ;;=================================================================  
  29.                  ;;  
  30.                  ;;  Syntax:  
  31.                  ;;  
  32.                  ;;      (Benchmark statements)  
  33.                  ;;  
  34.                  ;;          Where statements is a quoted list of statements.  
  35.                  ;;  
  36.                  ;;=================================================================  
  37.                  ;;  
  38.                  ;;  Example:  
  39.                  ;;  
  40.                  ;;      (BenchMark  
  41.                  ;;         '(  
  42.                  ;;              (1+ 1)  
  43.                  ;;              (+ 1 1)  
  44.                  ;;              (+ 1 1.0)  
  45.                  ;;              (+ 1.0 1.0)  
  46.                  ;;          )  
  47.                  ;;      )  
  48.                  ;;  
  49.                  ;;=================================================================  
  50.                  ;;  
  51.                  ;;  Output:  
  52.                  ;;  
  53.                  ;;      Elapsed milliseconds / relative speed for 32768 iteration(s):  
  54.                  ;;  
  55.                  ;;          (1+ 1)..........1969 / 1.09 <fastest>  
  56.                  ;;          (+ 1 1).........2078 / 1.03  
  57.                  ;;          (+ 1 1.0).......2125 / 1.01  
  58.                  ;;          (+ 1.0 1.0).....2140 / 1.00 <slowest>      
  59.                  ;;  
  60.                  ;;=================================================================  

  61.                  (statements / _LSet _RSet _ToString _Eval _Princ _Main)

  62.   ;;=================================================================  
  63.   ;;  
  64.   ;;  (_LSet text len fillChar)  
  65.   ;;  
  66.   ;;=================================================================  

  67.   (defun _LSet (text len fillChar / padding result)
  68.     (setq
  69.       padding (list (ascii fillChar))
  70.       result  (vl-string->list text)
  71.     )
  72.     (while
  73.       (< (length
  74.            (setq padding
  75.                   (append padding padding)
  76.            )
  77.          )
  78.          len
  79.       )
  80.     )
  81.     (while
  82.       (< (length
  83.            (setq result
  84.                   (append result padding)
  85.            )
  86.          )
  87.          len
  88.       )
  89.     )
  90.     (substr (vl-list->string result) 1 len)
  91.   )
  92.   ;;=================================================================  
  93.   ;;  
  94.   ;;  (_RSet text len fillChar)  
  95.   ;;  
  96.   ;;=================================================================  
  97.   (defun _RSet (text len fillChar / padding result)
  98.     (setq
  99.       padding (list (ascii fillChar))
  100.       result  (vl-string->list text)
  101.     )
  102.     (while
  103.       (< (length
  104.            (setq padding
  105.                   (append padding padding)
  106.            )
  107.          )
  108.          len
  109.       )
  110.     )
  111.     (while
  112.       (< (length
  113.            (setq result
  114.                   (append padding result)
  115.            )
  116.          )
  117.          len
  118.       )
  119.     )
  120.     (substr
  121.       (vl-list->string result)
  122.       (1+ (- (length result) len))
  123.     )
  124.   )
  125.   ;;=================================================================  
  126.   ;;  
  127.   ;;  (_ToString x)  
  128.   ;;  
  129.   ;;=================================================================  
  130.   (defun _ToString (x / result)
  131.     (if
  132.       (< (strlen
  133.            (setq result
  134.                   (vl-prin1-to-string x)
  135.            )
  136.          )
  137.          40
  138.       )
  139.        result
  140.        (strcat (substr result 1 36) "..." (chr 41))
  141.     )
  142.   )
  143.   ;;=================================================================  
  144.   ;;  
  145.   ;;  (_Eval statement iterations)  
  146.   ;;  
  147.   ;;=================================================================  
  148.   (defun _Eval (statement iterations / start)
  149.     (gc)
  150.     (setq start (getvar "millisecs"))
  151.     (repeat iterations (eval statement))
  152.     (- (getvar "millisecs") start)

  153.   )
  154.   ;;=================================================================  
  155.   ;;  
  156.   ;;  (_Princ x)  
  157.   ;;  
  158.   ;;=================================================================  
  159.   (defun _Princ        (x)
  160.     (princ x)
  161.     (princ)
  162.     ;; forces screen update  
  163.   )
  164.   ;;=================================================================  
  165.   ;;  
  166.   ;;  (_Main statements)  
  167.   ;;  
  168.   ;;=================================================================  
  169.   (defun _Main
  170.                (statements /              boundary         iterations timings
  171.                 slowest           fastest    lsetLen         rsetLen    index
  172.                 count
  173.                )

  174.     (setq
  175.       boundary 1000
  176.       iterations
  177.        1
  178.     )
  179.     (_Princ "Benchmarking ...")
  180.     (while
  181.       (or
  182.         (< (apply 'max
  183.                   (setq        timings
  184.                          (mapcar
  185.                            '(lambda (statement)
  186.                              (_Eval statement iterations)
  187.                            )
  188.                            statements
  189.                          )
  190.                   )
  191.            )
  192.            boundary
  193.         )
  194.         (< (apply 'min timings)
  195.            boundary
  196.         )
  197.       )
  198.        (setq iterations
  199.               (* 2 iterations)
  200.        )
  201.        (_Princ ".")
  202.     )
  203.     (_Princ
  204.       (strcat
  205.         "\rElapsed milliseconds / relative speed for "
  206.         (itoa iterations)
  207.         " iteration(s):\n\n"
  208.       )
  209.     )
  210.     (setq
  211.       slowest (float (apply 'max timings))
  212.       fastest (apply 'min timings)
  213.     )
  214.     (setq lsetLen
  215.            (+ 5
  216.               (apply 'max
  217.                      (mapcar 'strlen
  218.                              (setq statements
  219.                                     (mapcar '_ToString
  220.                                             statements
  221.                                     )
  222.                              )
  223.                      )
  224.               )
  225.            )
  226.     )
  227.     (setq rsetLen
  228.            (apply 'max
  229.                   (mapcar
  230.                     '
  231.                     (lambda (ms) (strlen (itoa ms)))
  232.                     timings
  233.                   )
  234.            )
  235.     )
  236.     (setq
  237.       index 0
  238.       count (length statements)
  239.     )
  240.     (foreach pair
  241.              (vl-sort
  242.                     (mapcar 'cons statements timings)
  243.                     '
  244.                     (lambda (a b) (< (cdr a) (cdr b)))
  245.                   )
  246.       ((lambda (pair / ms)
  247.          (_Princ
  248.            (strcat
  249.              "    "
  250.              (_LSet (car pair) lsetLen ".")
  251.              (_RSet
  252.                (itoa (setq ms (cdr pair)))
  253.                rsetLen
  254.                "."
  255.              )
  256.              " / "
  257.              (rtos (/ slowest ms) 2 2)
  258.              (cond
  259.                ((eq 1 (setq index (1+ index))) " <fastest>")
  260.                ((eq index count) " <slowest>")
  261.                ("")
  262.              )
  263.              "\n"
  264.            )
  265.          )
  266.        )
  267.         pair
  268.       )
  269.     )
  270.     (princ)
  271.   )
  272.   ;;=================================================================  
  273.   ;;  
  274.   ;;  Program is defined, let's rock and roll ...  
  275.   ;;  
  276.   ;;=================================================================  
  277.   (_Main statements)
  278. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2008-6-12 13:12:37 | 显示全部楼层
Benchmark,测试结果与里面的表达式排序有关!不同排序会有不同测试结果.
上面的确实是最慢的!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-1 16:26 , Processed in 0.378208 second(s), 45 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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