Author Topic: Single dimensional list to duoble dimensional  (Read 8419 times)

0 Members and 1 Guest are viewing this topic.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Single dimensional list to duoble dimensional
« on: April 04, 2012, 09:38:27 AM »
Many a time you need a list of coordinates, but when working with ActiveX mostly you get a flat array of numbers. Say with a polyline's Coordinates property.

So here I'm attempting a quick-fix to change a list like (X Y X Y X Y ...) into ((X Y) (X Y) (X Y)).

First idea:
Code: [Select]
(defun list-group (lst n / res item)
  (while lst
    (setq item nil)
    (repeat n (setq item (cons (car lst) item) lst (cdr lst)))
    (setq res (cons (reverse item) res)))
  (reverse res))
Some sample code:
Code: [Select]
_$ (list-group '(1 2 3 4 5 6 7 8 9) 3)
((1 2 3) (4 5 6) (7 8 9))
_$ (list-group '(1 2 3 4 5 6 7 8 9 10) 3)
((1 2 3) (4 5 6) (7 8 9) (10 nil nil))
Clearly if the length of the list is not divisible by the group-by number, you're going to get those nils at the end.

I'm trying to steer clear of nth, since it's rather less efficient than most other methods. Otherwise a simple double increment integer index would have been the most straight-forward principle. Something like this:
Code: [Select]
(defun list-group-i (lst n / item res i j)
  (setq i (length lst))
  (while (>= (setq i (1- i)) 0)
    (setq j n item nil)
    (while (>= (setq j (1- j)) 0)
      (setq item (cons (nth (+ i j) lst) item)))
    (setq res (cons item res) i (- i n -1)))
  res)

And yes I have thought of making that 1st one only use one reverse on the main list and then work backwards. Though then what should happen to the case where the list length is not divisible by the grouping count? Perhaps this:
Code: [Select]
(defun list-group1 (lst n / res item)
  (setq lst (reverse lst))
  (repeat (- n (rem (length lst) n)) (setq lst (cons nil lst)))
  (while lst
    (setq item nil)
    (repeat n (setq item (cons (car lst) item) lst (cdr lst)))
    (setq res (cons item res)))
  res)

Results thus far on a list of 5000 length:
Code: [Select]
Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):

    (LIST-GROUP1 LST 5)......1030 / 6.53 <fastest>
    (LIST-GROUP LST 5).......1061 / 6.34
    (LIST-GROUP-I LST 5).....6723 / 1 <slowest>
Clearly the indexed version is way slower than the others. Anyone have any other ideas?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Single dimensional list to duoble dimensional
« Reply #2 on: April 04, 2012, 09:46:26 AM »
This is what I have in my library. I'm not saying it's faster, in fact it's likely slower than any of the ones in this thread (no time to bench). It's rather simplistic -- I ante it up soley because it does things differently; sharing differences being the swamp way:

Code: [Select]
(defun _SubLists ( lst n / sublist result )

    ;;  Given:  a list of (1 2 3 4 5 6 7 8)
    ;; 
    ;;          and n values of 2, 3 and 4
    ;;
    ;;  Return: ((1 2) (3 4) (5 6) (7 8))
    ;;          ((1 2 3) (4 5 6) (7 8))
    ;;          ((1 2 3 4) (5 6 7 8))
    ;;
    ;;  respectively.

    (foreach x lst       
        (if (eq n (length (setq sublist (cons x sublist))))
            (setq
                result  (cons (reverse sublist) result)
                sublist nil
            )           
        )       
    )
   
    (reverse
        (if sublist
            (cons (reverse sublist) result)
            result
        )
    )   
)

FWIW, cheers.

PS: It doesn't return nil values where the original list is not evenly divisible by the sublist length.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #3 on: April 04, 2012, 09:59:06 AM »
... I'm not saying it's faster ...
Strange that you should mention that ... or perhaps not  :whistle:
Code: [Select]
Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s):

    (_SUBLISTS LST 5)...........1716 / 1.15 <fastest>
    (LIST-GROUP1 LST 5).........1903 / 1.03
    (LM:GROUPBYNUM-R LST 5).....1950 / 1.01
    (LIST-GROUP LST 5)..........1966 / 1
    (LM:GROUPBYNUM LST 5).......1966 / 1 <slowest>
Obviously I axed the embarrassing index version  :ugly:

Edit: I'm not too sure if this is "wrong" per say:
Code: [Select]
_$ (_Sublists '(1 2 3 4 5 6 7 8 9 10) 3)
((1 2 3) (4 5 6) (7 8 9) (10))
Effectively the same thing isn't it?

And Lee, though your recursive is faster than your iterative (only just), I'd be unwilling to use it on large lists - remember that ~20k error cut-off on recursion.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #4 on: April 04, 2012, 10:08:59 AM »
Challenge thread:

http://www.theswamp.org/index.php?topic=32428.0

Challenge thread 2:

http://www.theswamp.org/index.php?topic=5108.0
Typical!

There are no more challenges ... only redoing the same old thing again!

Sorry guys, I should've searched before starting this thread.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #5 on: April 04, 2012, 11:10:55 AM »
Whahaha!

I thought MP was onto a good idea, So I thought I'd modify a bit to make less reverses (as per my previous code):
Code: [Select]
(defun list-group (lst n / sub res)
  (setq lst (reverse lst))
  (repeat (- n (rem (length lst) n)) (setq lst (cons nil lst)))
  (foreach x lst
    (if (eq n (length (setq sub (cons x sub))))
      (setq res (cons sub res) sub nil)))
  (if sub
    (cons sub res)
    res))

Just look at the benchmarking including the fastest from those other threads:
Code: [Select]
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):

    (GBN_1_EV LST 5)...................1622 / 3.11 <fastest>
    (LIST-GROUP LST 5).................3947 / 1.28
    (GROUPBYNUM_MAC4 LST 5)............4025 / 1.25
    (_SUBLISTS LST 5)..................4072 / 1.24
    (GROUPBYNUM_MAC3 LST 5)............4228 / 1.19
    (LIST-GROUP-STEPREVERSE LST 5).....4555 / 1.11
    (LM:GROUPBYNUM LST 5)..............4633 / 1.09
    (LM:GROUPBYNUM-R LST 5)............4633 / 1.09
    (GROUPBYNUM_MAC2 LST 5)............4633 / 1.09
    (GBN LST 5)........................4696 / 1.07
    (LIST-GROUP-STEP LST 5)............4711 / 1.07
    (WIZ-GRP LST 5)....................4789 / 1.05
    (GROUPBYNUM_VK LST 5)..............4790 / 1.05
    (GROUPBYNUM_MAC LST 5).............4820 / 1.05
    (SPLIT LST 5)......................5039 / 1 <slowest>
Should've remembered from my programming lectures: "Divide and conquer is what makes Quick Sort live up to its name".

Leave it for Evgeniy to remember to do this!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Single dimensional list to duoble dimensional
« Reply #6 on: April 04, 2012, 11:46:15 AM »
Looks like my attempt did not make the cut.  :-(
http://www.theswamp.org/index.php?topic=5108.msg61975#msg61975
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #7 on: April 04, 2012, 11:55:41 AM »
Looks like my attempt did not make the cut.  :(
http://www.theswamp.org/index.php?topic=5108.msg61975#msg61975
Sorry, missed yours from that huge list of attempts.
Code: [Select]
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):

    (GBN_1_EV LST 5)...................1654 / 3.1 <fastest>
    (LIST-GROUP LST 5).................3947 / 1.3
    (_SUBLISTS LST 5)..................4056 / 1.27
    (GROUPBYNUM_MAC4 LST 5)............4134 / 1.24
    (GROUPBYNUM_MAC3 LST 5)............4259 / 1.2
    (LIST-GROUP-STEPREVERSE LST 5).....4524 / 1.13
    (LM:GROUPBYNUM LST 5)..............4649 / 1.1
    (LM:GROUPBYNUM-R LST 5)............4649 / 1.1
    (GBN LST 5)........................4649 / 1.1
    (GROUPBYNUM_MAC2 LST 5)............4665 / 1.1
    (LIST-GROUP-STEP LST 5)............4680 / 1.1
    (GROUPBYNUM_MAC LST 5).............4851 / 1.06
    (GROUPBYNUM_VK LST 5)..............4852 / 1.06
    (WIZ-GRP LST 5)....................4882 / 1.05
    (SPLIT LST 5)......................5023 / 1.02
    (GROUPITEMS LST 5).................5132 / 1 <slowest>
Oops ... I think I could've lied and said yours "just" didn't make the cut!  :pissed:
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Single dimensional list to duoble dimensional
« Reply #8 on: April 04, 2012, 12:03:17 PM »
Great, I get the consolation Prize.  :ugly:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #9 on: April 04, 2012, 12:36:05 PM »
OK, doing the same to Evgeniy's code as I did to MP's:
Code - Auto/Visual Lisp: [Select]
  1. (defun list-gbn (lst n / i func res list-gbn-temp)
  2.   (setq func '(a) i 5 lst (reverse lst))
  3.   (repeat (- n (rem (length lst) n)) (setq lst (cons nil lst)))
  4.   (while (> (setq i (1- i)) 0)
  5.     (repeat (/ n i)
  6.       (setq func (cons (nth i '(nil
  7.                                 (setq a (cons (car lst) a) lst (cdr lst))
  8.                                 (setq a (cons (cadr lst) (cons (car lst) a)) lst (cddr lst))
  9.                                 (setq a (cons (caddr lst) (cons (cadr lst) (cons (car lst) a))) lst (cdddr lst))
  10.                                 (setq a (cons (cadddr lst) (cons (caddr lst) (cons (cadr lst) (cons (car lst) a)))) lst (cddddr lst))))
  11.                        func)))
  12.     (setq n (rem n i)))
  13.   (eval (cons 'defun (cons 'list-gbn-temp (cons '(a) func))))
  14.   (while lst (setq res (cons (list-gbn-temp nil) res)))
  15.   res)
And lo and behold, I get another ounce of speed out of it!  :lmao:
Code: [Select]
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):

    (LIST-GBN LST 5).....1591 / 1.05 <fastest>
    (GBN_1_EV LST 5).....1669 / 1 <slowest>
Also tried to make the original a bit more "elegant" ... though I'm still not happy with those 4 setq's.
« Last Edit: April 04, 2012, 12:39:49 PM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #10 on: April 04, 2012, 12:45:58 PM »
Oops, silly me - I forgot about this case:
Code: [Select]
$ (list-gbn '(1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10) 5)
((1 2 3 4 5) (6 7 8 9 10) (1 2 3 4 5) (6 7 8 9 10) (nil nil nil nil nil))
Here's the fix:
Code - Auto/Visual Lisp: [Select]
  1. (defun list-gbn (lst n / r i func res list-gbn-temp)
  2.   (setq func '(a) i 5 lst (reverse lst))
  3.   (if (> (setq r (rem (length lst) n)) 0)
  4.     (repeat (- n r) (setq lst (cons nil lst))))
  5.   (while (> (setq i (1- i)) 0)
  6.     (repeat (/ n i)
  7.       (setq func (cons (nth i '(nil
  8.                                 (setq a (cons (car lst) a) lst (cdr lst))
  9.                                 (setq a (cons (cadr lst) (cons (car lst) a)) lst (cddr lst))
  10.                                 (setq a (cons (caddr lst) (cons (cadr lst) (cons (car lst) a))) lst (cdddr lst))
  11.                                 (setq a (cons (cadddr lst) (cons (caddr lst) (cons (cadr lst) (cons (car lst) a)))) lst (cddddr lst))))
  12.                        func)))
  13.     (setq n (rem n i)))
  14.   (eval (cons 'defun (cons 'list-gbn-temp (cons '(a) func))))
  15.   (while lst (setq res (cons (list-gbn-temp nil) res)))
  16.   res)
And the benchmark:
Code: [Select]
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):

    (LIST-GBN LST 5).....1591 / 1.04 <fastest>
    (GBN_1_EV LST 5).....1653 / 1 <slowest>
Still a whisker faster!  :kewl:
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Single dimensional list to duoble dimensional
« Reply #11 on: April 04, 2012, 02:19:29 PM »
Nice reworking of Evgeniy's algorithm Irne  :-)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #12 on: April 05, 2012, 01:55:09 AM »
Nice reworking of Evgeniy's algorithm Irne  :)
Thanks! After re-reading his code several times I finally figured out what was going on ... and then realized: "But this can be combined into a loop can't it?"

Anyhow, as I've stated: "I'm still not happy with it." Those 4 setq's in the nth call is too much double typing - there should be a way of combining that into a loop as well. Of course that would make it slightly less efficient - though not by much as it's a once-off in the function.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #13 on: April 05, 2012, 05:12:38 AM »
Actually this principle is quite useful in other systems. I've incorporated the same in my AutoLisp Extender library's NthCDR and FirstN / LastN functions.

Thank you ElpanovEvgeniy! I've cited you as the originator of such code, without it I'd probably never have though of doing it this way.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Stefan

  • Bull Frog
  • Posts: 319
  • The most I miss IRL is the Undo button
Re: Single dimensional list to duoble dimensional
« Reply #14 on: April 05, 2012, 07:10:24 AM »
A little too late, but here is mine
Code - Auto/Visual Lisp: [Select]
  1. (defun gbn (l n / s r)
  2.   (repeat (/ (length l) n)
  3.     (setq r (cons (reverse (repeat n (setq s (cons (car l) s) l (cdr l)) s)) r) s nil)
  4.     )
  5.   (reverse (if l (cons l r) r))
  6.   )

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #15 on: April 06, 2012, 02:40:16 AM »
Never too late  :pissed:

I've had to rename yours to gbn2, since there was a gbn already:
Code: [Select]
Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s):

    (LIST-GBN LST 5)...................1232 / 2.55 <fastest>
    (GBN_1_EV LST 5)...................1294 / 2.42
    (GROUPBYNUM_MAC3 LST 5)............1763 / 1.78
    (LIST-GROUP-STEPREVERSE LST 5).....1794 / 1.75
    (GROUPBYNUM_MAC4 LST 5)............2590 / 1.21
    (LIST-GROUP LST 5).................2621 / 1.2
    (_SUBLISTS LST 5)..................2652 / 1.18
    (GBN2 LST 5).......................3027 / 1.04
    (LM:GROUPBYNUM-R LST 5)............3120 / 1.01
    (LM:GROUPBYNUM LST 5)..............3136 / 1
    (GBN LST 5)........................3136 / 1 <slowest>
Not bad ... made the top 10!

Strange though, I did the previous test on another PC. Used the exact same test case:
Code: [Select]
(setq lst nil n 0)
(repeat 5000 (setq lst (cons n lst) n (1+ n)))
The two PC's are extremely close to being identical (both i7-2600, both 16GB ram, both Win7 Pro, both Vanilla 2012). Yet there's some discrepancies in the benchmarking. I've run the benchmarking 5 times now and get similar results each time. Must be something strange running on the background in one but not the other.

Perhaps my AV, the 1st had ClamWin+MSSE, this one's got Avast!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

VovKa

  • Water Moccasin
  • Posts: 1631
  • Ukraine
Re: Single dimensional list to duoble dimensional
« Reply #16 on: April 06, 2012, 03:01:19 AM »
it's time to test all these compiled
you'll be surprised  8-)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #17 on: April 06, 2012, 04:52:24 AM »
Yes, that would probably make a lot of difference!

Uncompiled (Interpreted):
Code: [Select]
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):

    (LIST-GBN LST 5)............1029 / 3.5 <fastest>
    (GBN_1_EV LST 5)............1233 / 2.92
    (GROUPBYNUM_MAC4 LST 5).....2090 / 1.72
    (GROUPBYNUM_MAC3 LST 5).....2184 / 1.65
    (LIST-GBN2 LST 5)...........2386 / 1.51
    (LM:GROUPBYNUM-R LST 5).....2605 / 1.38
    (SPLIT LST 5)...............2636 / 1.37
    (WIZ-GRP LST 5).............2793 / 1.29
    (_SUBLISTS LST 5)...........2823 / 1.28
    (GROUPITEMS LST 5)..........2871 / 1.26
    (LM:GROUPBYNUM LST 5).......2964 / 1.22
    (LIST-GROUP-STEP LST 5).....2964 / 1.22
    (GROUPBYNUM_MAC2 LST 5).....3229 / 1.12
    (GROUPBYNUM_MAC LST 5)......3323 / 1.08
    (GBN2 LST 5)................3604 / 1 <slowest>

Compiled to FAS using Standard compilation:
Code: [Select]
Benchmarking .............Elapsed milliseconds / relative speed for 1024 iteration(s):

    (LIST-GBN LST 5)............1919 / 3.83 <fastest>
    (LM:GROUPBYNUM-R LST 5).....1950 / 3.77
    (LIST-GROUP-STEP LST 5).....1965 / 3.74
    (LM:GROUPBYNUM LST 5).......1966 / 3.74
    (GROUPBYNUM_MAC2 LST 5).....1981 / 3.71
    (GBN_1_EV LST 5)............2013 / 3.65
    (GBN2 LST 5)................2137 / 3.44
    (_SUBLISTS LST 5)...........2153 / 3.41
    (LIST-GBN2 LST 5)...........2293 / 3.2
    (GROUPBYNUM_MAC4 LST 5).....2745 / 2.68
    (GROUPBYNUM_MAC3 LST 5).....2933 / 2.5
    (GROUPITEMS LST 5)..........3245 / 2.26
    (SPLIT LST 5)...............3978 / 1.85
    (WIZ-GRP LST 5).............4118 / 1.78
    (GROUPBYNUM_MAC LST 5)......7347 / 1 <slowest>

Compiled to FAS using optimize & indirect linking:
Code: [Select]
Benchmarking .............Elapsed milliseconds / relative speed for 1024 iteration(s):

    (LIST-GBN LST 5)............1934 / 3.19 <fastest>
    (LM:GROUPBYNUM-R LST 5).....1966 / 3.14
    (GROUPBYNUM_MAC2 LST 5).....1981 / 3.12
    (LM:GROUPBYNUM LST 5).......1981 / 3.12
    (LIST-GROUP-STEP LST 5).....1997 / 3.09
    (GBN_1_EV LST 5)............2028 / 3.05
    (GBN2 LST 5)................2153 / 2.87
    (_SUBLISTS LST 5)...........2153 / 2.87
    (LIST-GBN2 LST 5)...........2309 / 2.68
    (GROUPBYNUM_MAC4 LST 5).....2777 / 2.22
    (GROUPBYNUM_MAC3 LST 5).....2901 / 2.13
    (GROUPITEMS LST 5)..........3260 / 1.9
    (SPLIT LST 5)...............3526 / 1.75
    (WIZ-GRP LST 5).............3713 / 1.66
    (GROUPBYNUM_MAC LST 5)......6178 / 1 <slowest>

And lastly, FAS with optimized & linked directly:
Code: [Select]
Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s):

    (GROUPBYNUM_MAC2 LST 5)......1903 / 5.89 <fastest>
    (LIST-GROUP-STEP LST 5)......1935 / 5.79
    (LM:GROUPBYNUM LST 5)........1950 / 5.74
    (LM:GROUPBYNUM-R LST 5)......2012 / 5.57
    (GBN2 LST 5).................2309 / 4.85
    (GROUPBYNUM_MAC4 LST 5)......2324 / 4.82
    (_SUBLISTS LST 5)............2356 / 4.75
    (LIST-GBN2 LST 5)............2387 / 4.69
    (GROUPBYNUM_MAC3 LST 5)......2449 / 4.57
    (GROUPITEMS LST 5)...........2668 / 4.2
    (SPLIT LST 5)................3463 / 3.23
    (LIST-GBN LST 5).............3697 / 3.03
    (WIZ-GRP LST 5)..............4399 / 2.55
    (GBN_1_EV LST 5).............4493 / 2.49
    (GROUPBYNUM_MAC LST 5)......11201 / 1 <slowest>

Quite a lot of discrepancy isn't there? Here's the test code:
Code - Auto/Visual Lisp: [Select]
  1. (setq funcs '(LIST-GBN2 GBN2 LIST-GBN GROUPITEMS GROUPBYNUM_MAC4 GBN_1_EV WIZ-GRP SPLIT GROUPBYNUM_VK GROUPBYNUM_MAC3 GROUPBYNUM_MAC2 GROUPBYNUM_MAC
  2.     LIST-GROUP _SUBLISTS LM:GROUPBYNUM-R LM:GROUPBYNUM LIST-GROUP-STEPREVERSE LIST-GROUP-IDX LIST-GROUP-STEP))
  3. (setq lst nil n 0)
  4. (repeat 5000 (setq lst (cons n lst) n (1+ n)))
  5. (load "list-group.lsp")
  6. (benchmark (mapcar '(lambda (f) (cons f '(lst 5)))
  7.                    (vl-remove-if-not
  8.                      '(lambda (f) (equal (apply f (list '(1 2 3 4 5 6 7 8 9 0) 5)) '((1 2 3 4 5) (6 7 8 9 0))))
  9.                      funcs)))
  10. (vlisp-compile 'st "list-group.lsp" "list-group-st.fas")
  11. (load "list-group-st.fas")
  12. (benchmark (mapcar '(lambda (f) (cons f '(lst 5)))
  13.                    (vl-remove-if-not
  14.                      '(lambda (f) (equal (apply f (list '(1 2 3 4 5 6 7 8 9 0) 5)) '((1 2 3 4 5) (6 7 8 9 0))))
  15.                      funcs)))
  16. (vlisp-compile 'lsm "list-group.lsp" "list-group-lsm.fas")
  17. (load "list-group-lsm.fas")
  18. (benchmark (mapcar '(lambda (f) (cons f '(lst 5)))
  19.                    (vl-remove-if-not
  20.                      '(lambda (f) (equal (apply f (list '(1 2 3 4 5 6 7 8 9 0) 5)) '((1 2 3 4 5) (6 7 8 9 0))))
  21.                      funcs)))
  22. (vlisp-compile 'lsa "list-group.lsp" "list-group-lsa.fas")
  23. (load "list-group-lsa.fas")
  24. (benchmark (mapcar '(lambda (f) (cons f '(lst 5)))
  25.                    (vl-remove-if-not
  26.                      '(lambda (f) (equal (apply f (list '(1 2 3 4 5 6 7 8 9 0) 5)) '((1 2 3 4 5) (6 7 8 9 0))))
  27.                      funcs)))
There were some warnings in the compiling output, so I added a check to omit any functions not performing correctly. Also to make the benchmark not have to run for days, I've omitted those just taking too long  ;)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Single dimensional list to duoble dimensional
« Reply #18 on: April 06, 2012, 05:15:23 AM »
Sorry to burst the bubble on your extensive testing Irneb, but you didn't rename the recursive call in my 'LM:GroupByNum-R' function, and my 'GroupByNum_Mac2' function is the same as the iterative 'LM:GroupByNum' function I posted on my site  :wink:

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #19 on: April 06, 2012, 05:21:32 AM »
Just realized as I was trying to make a benchmark when VLIDE was not loaded. Anyhow, that wasn't the only mistakes  :ugly:

Sorry guys! Here's the benchmarking on a clean start of ACAD:
Quote
Command: (load "Benchmark")
BENCHMARK

Command: (load "BenchTest")
Elapsed milliseconds / relative speed for 1024 iteration(s):

    (LIST-GBN LST 5)............1591 / 3.84 <fastest>
    (GBN_1_EV LST 5)............1654 / 3.7
    (LIST-GBN2 LST 5)...........2434 / 2.51
    (LIST-GROUP-STEP LST 5).....2667 / 2.29
    (GROUPBYNUM_MAC2 LST 5).....2684 / 2.28
    (LM:GROUPBYNUM LST 5).......2715 / 2.25
    (GROUPBYNUM_MAC LST 5)......2776 / 2.2
    (GBN2 LST 5)................2823 / 2.17
    (GROUPBYNUM_MAC4 LST 5).....2855 / 2.14
    (LM:GROUPBYNUM-R LST 5).....2870 / 2.13
    (GROUPBYNUM_MAC3 LST 5).....2948 / 2.07
    (_SUBLISTS LST 5)...........3214 / 1.9
    (GROUPITEMS LST 5)..........3245 / 1.88
    (SPLIT LST 5)...............3744 / 1.63
    (WIZ-GRP LST 5).............3806 / 1.61
    (GROUPBYNUM_VK LST 5).......6115 / 1 <slowest>
Elapsed milliseconds / relative speed for 1024 iteration(s):

    (LIST-GBN LST 5)............1560 / 4.14 <fastest>
    (GBN_1_EV LST 5)............1591 / 4.06
    (GROUPBYNUM_MAC2 LST 5).....1762 / 3.67
    (LIST-GROUP-STEP LST 5).....1778 / 3.63
    (LM:GROUPBYNUM LST 5).......1779 / 3.63
    (_SUBLISTS LST 5)...........1919 / 3.37
    (GBN2 LST 5)................1934 / 3.34
    (LM:GROUPBYNUM-R LST 5).....2043 / 3.16
    (LIST-GBN2 LST 5)...........2075 / 3.11
    (GROUPBYNUM_MAC LST 5)......2075 / 3.11
    (GROUPBYNUM_MAC4 LST 5).....2574 / 2.51
    (GROUPBYNUM_MAC3 LST 5).....2637 / 2.45
    (GROUPITEMS LST 5)..........2949 / 2.19
    (WIZ-GRP LST 5).............3432 / 1.88
    (SPLIT LST 5)...............3495 / 1.85
    (GROUPBYNUM_VK LST 5).......6458 / 1 <slowest>
Elapsed milliseconds / relative speed for 1024 iteration(s):

    (GBN_1_EV LST 5)............1592 / 3.95 <fastest>
    (LIST-GBN LST 5)............1607 / 3.91
    (GROUPBYNUM_MAC2 LST 5).....1763 / 3.57
    (LM:GROUPBYNUM LST 5).......1763 / 3.57
    (LIST-GROUP-STEP LST 5).....1778 / 3.54
    (_SUBLISTS LST 5)...........1919 / 3.28
    (GBN2 LST 5)................2028 / 3.1
    (GROUPBYNUM_MAC LST 5)......2059 / 3.05
    (LM:GROUPBYNUM-R LST 5).....2059 / 3.05
    (LIST-GBN2 LST 5)...........2433 / 2.58
    (GROUPBYNUM_MAC4 LST 5).....2574 / 2.44
    (GROUPBYNUM_MAC3 LST 5).....2667 / 2.36
    (GROUPITEMS LST 5)..........3011 / 2.09
    (SPLIT LST 5)...............3338 / 1.88
    (WIZ-GRP LST 5).............3432 / 1.83
    (GROUPBYNUM_VK LST 5).......6287 / 1 <slowest>
Elapsed milliseconds / relative speed for 2048 iteration(s):

    (GROUPBYNUM_MAC2 LST 5).....1591 / 2.96 <fastest>
    (LM:GROUPBYNUM LST 5).......1591 / 2.96
    (LIST-GROUP-STEP LST 5).....1623 / 2.9
    (_SUBLISTS LST 5)...........1966 / 2.4
    (GBN2 LST 5)................1997 / 2.36
    (LIST-GBN2 LST 5)...........2060 / 2.29
    (GROUPBYNUM_MAC4 LST 5).....2106 / 2.24
    (LM:GROUPBYNUM-R LST 5).....2106 / 2.24
    (GROUPBYNUM_MAC3 LST 5).....2137 / 2.2
    (GROUPBYNUM_MAC LST 5)......2137 / 2.2
    (GROUPITEMS LST 5)..........2340 / 2.01
    (LIST-GBN LST 5)............3042 / 1.55
    (GBN_1_EV LST 5)............3104 / 1.52
    (SPLIT LST 5)...............3183 / 1.48
    (WIZ-GRP LST 5).............3619 / 1.3
    (GROUPBYNUM_VK LST 5).......4711 / 1 <slowest>
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

VovKa

  • Water Moccasin
  • Posts: 1631
  • Ukraine
Re: Single dimensional list to duoble dimensional
« Reply #20 on: April 06, 2012, 06:54:46 AM »
Quote
    (GROUPBYNUM_MAC2 LST 5).....1591 / 2.96 <fastest>
    (LM:GROUPBYNUM LST 5).......1591 / 2.96
    (LIST-GROUP-STEP LST 5).....1623 / 2.9
    (_SUBLISTS LST 5)...........1966 / 2.4
    (GBN2 LST 5)................1997 / 2.36
    (LIST-GBN2 LST 5)...........2060 / 2.29
    (GROUPBYNUM_MAC4 LST 5).....2106 / 2.24
    (LM:GROUPBYNUM-R LST 5).....2106 / 2.24
    (GROUPBYNUM_MAC3 LST 5).....2137 / 2.2
    (GROUPBYNUM_MAC LST 5)......2137 / 2.2
    (GROUPITEMS LST 5)..........2340 / 2.01
    (LIST-GBN LST 5)............3042 / 1.55
    (GBN_1_EV LST 5)............3104 / 1.52
    (SPLIT LST 5)...............3183 / 1.48
    (WIZ-GRP LST 5).............3619 / 1.3
    (GROUPBYNUM_VK LST 5).......4711 / 1 <slowest>
you can't fool the compiler :)
as soon as we are going to use/sell lsa-compiled applications we'd better stick to simple 'basic' loops

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Single dimensional list to duoble dimensional
« Reply #21 on: April 06, 2012, 07:10:32 AM »
Yes, it seems that way doesn't it. Recursion doesn't seem to gain anything by compiling, and even less for those self-modifying functions of Evgeniy and myself. That's why I wrote the list-gbn2 - it basically uses the same idea, but places it inside a repeat loop and cond statement - instead of generating a defun on the fly. It doesn't help too much though, with the direct linking it seems that a cddddr doesn't perform better than a repetition of cdr - and the overhead required to test if four repetitions can be combined into one makes for a less efficient loop. I think that's why it doesn't gain as much as the other looping algorithms.

Still, it's only if you go the direct linking way when the speed of those self-modifying code is nullified. See in the other 2 types of compilation - the normal looping algorithms only just reach the same speed (i.e. 2-3 times faster).

So I guess it's a situation of your deliverable. Are you going to compile it? If so can you use direct linking? If only interpreted I'd definitely go for the self-modifiers, otherwise I'd go with Lee's iterative method.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.