Author Topic: vl-position vs member  (Read 8887 times)

0 Members and 1 Guest are viewing this topic.

ymg

  • Guest
vl-position vs member
« on: April 30, 2015, 01:30:01 PM »
Just reporting a little benchmark I did with MP's program.

When testing a list to know if a point is present in it,
we may use the following.

The point list was 5000 pts long and we are searching for the 4800th point:

Quote
(setq p (nth 4800 pl))
(4783.64 2541.82 128.687)
_$ (benchmark '((vl-position p pl) (member p pl)))
Benchmarking ................Elapsed milliseconds / relative speed for 8192 iteration(s):

    (VL-POSITION P PL).....1232 / 3.56 <fastest>
    (MEMBER P PL)..........4384 / 1.00 <slowest>
_$
_$ (benchmark '((vl-position p pl) (member p pl)))
Benchmarking ................Elapsed milliseconds / relative speed for 8192 iteration(s):

    (VL-POSITION P PL).....1217 / 3.58 <fastest>
    (MEMBER P PL)..........4352 / 1.00 <slowest>

I remember testing it before and my conclusion then
was that vl-position was marginally faster.

So I am bit surprised to see that on this length of
list, it is actually about 3.6 times faster.

ymg

mailmaverick

  • Bull Frog
  • Posts: 493
Re: vl-position vs member
« Reply #1 on: April 30, 2015, 11:43:37 PM »
Nice observation.

But I fail to understand that why vl- commands are faster than basic functions of AutoLISP ?

Also, it would be interesting to know that whether vla- and vlax- commands are also faster than basic functions of AutoLISP ?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: vl-position vs member
« Reply #2 on: May 01, 2015, 12:49:46 AM »
The distinction is not between Vl- and AutoLisp but rather that one returns an index while the other returns a list of the found item and all items that follow.





kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: vl-position vs member
« Reply #3 on: May 01, 2015, 03:59:36 AM »
The distinction is not between Vl- and AutoLisp but rather that one returns an index while the other returns a list of the found item and all items that follow.
This is a sample that use vl-position to get a member result
Code: [Select]
; 2014/02/19 - n (Position) Nth like
(defun ALE_List_NthCdr (n l)   
  (repeat (/       n              1000) (setq l (Cd1000r l)))   
  (repeat (/ (setq n (rem n 1000)) 100) (setq l (Cd100r  l)))   
  (repeat (/ (setq n (rem n  100))  10) (setq l (Cd10r   l)))   
  (repeat (/ (setq n (rem n   10))   4) (setq l (cddddr  l)))   
  (repeat (rem n 4)                     (setq l (cdr     l)))   
  l   
)
; 2014/03/01 for VERY long lists
(defun ALE_List_NthCdrL (n l)   
  (repeat (/       n               10000) (setq l (Cd10000r l)))   
  (repeat (/ (setq n (rem n 10000)) 1000) (setq l (Cd1000r  l)))   
  (repeat (/ (setq n (rem n  1000))  100) (setq l (Cd100r   l)))   
  (repeat (/ (setq n (rem n   100))   10) (setq l (Cd10r    l)))   
  (repeat (/ (setq n (rem n    10))    4) (setq l (cddddr   l)))   
  (repeat            (rem n     4)        (setq l (cdr      l)))   
  l   
)
; faster of member on long lists or short (1000 elements) if Item is near final position
(defun ALE_List_Member (i l)
  (ALE_List_NthCdr (vl-position i l) l)
)
(defun Cd10r (l)
  (cddddr(cddddr(cddr l)))
)
(defun Cd100r (l)
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr l)))))))))))))))))))))))))
)

(defun Cd10000r (l)
  (Cd1000r(Cd1000r(Cd1000r(Cd1000r(Cd1000r(Cd1000r
  (Cd1000r(Cd1000r(Cd1000r(Cd1000r l))))))))))
)

(defun Cd100000r (l)
  (Cd10000r(Cd10000r(Cd10000r(Cd10000r(Cd10000r(Cd10000r
  (Cd10000r(Cd10000r(Cd10000r(Cd10000r l))))))))))
)

(defun Cd1000r (l)
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr(cddddr(cddddr
  (cddddr(cddddr(cddddr(cddddr(cddddr l))))))))))))
  )))))))))))))))))))))))))))))))))))))))))))))))))
  )))))))))))))))))))))))))))))))))))))))))))))))))
  )))))))))))))))))))))))))))))))))))))))))))))))))
  )))))))))))))))))))))))))))))))))))))))))))))))))
  ))))))))))))))))))))))))))))))))))))))))))
)
;
(defun Cd10000r (l)
  (Cd1000r(Cd1000r(Cd1000r(Cd1000r(Cd1000r(Cd1000r
  (Cd1000r(Cd1000r(Cd1000r(Cd1000r l))))))))))
)

ymg

  • Guest
Re: vl-position vs member
« Reply #4 on: May 01, 2015, 07:05:17 PM »
mailmaverick,

Kerry is absolutely right.

These are different functions.

The benchmark is valid only when you test for the presence or
absence of an item in a list.

If you need to extract the item member gives it to you
with the rest of the list. So (car l), very fast.

With vl-position now you need to extract the item
with (nth pos l) and things slows down seriously there.

ymg
« Last Edit: May 01, 2015, 07:10:58 PM by ymg »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: vl-position vs member
« Reply #5 on: May 01, 2015, 07:22:51 PM »
The distinction is not between Vl- and AutoLisp but rather that one returns an index while the other returns a list of the found item and all items that follow.
This is a sample that use vl-position to get a member result
Code: [Select]
; 2014/02/19 - n (Position) Nth like
< .. >


I know only 2 people who could author code like that ... and one of them is in the same therapy session as me.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: vl-position vs member
« Reply #6 on: May 02, 2015, 02:35:00 AM »
I know only 2 people who could author code like that ... and one of them is in the same therapy session as me.
Yes :-D

I guess that comes via this discussion: http://www.theswamp.org/index.php?topic=46419.5
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: vl-position vs member
« Reply #7 on: May 02, 2015, 04:00:53 AM »
The distinction is not between Vl- and AutoLisp but rather that one returns an index while the other returns a list of the found item and all items that follow.
This is a sample that use vl-position to get a member result
Code: [Select]
; 2014/02/19 - n (Position) Nth like
< .. >
I know only 2 people who could author code like that ... and one of them is in the same therapy session as me.
:2funny: :uglystupid2: :knuppel2: :devilsidesmile:                                         :) :) :)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: vl-position vs member
« Reply #8 on: May 02, 2015, 04:05:01 AM »
I know only 2 people who could author code like that ... and one of them is in the same therapy session as me.
Yes ;D

I guess that comes via this discussion: http://www.theswamp.org/index.php?topic=46419.5
:nerdyembarassed: you are the third!    :)

http://www.theswamp.org/index.php?topic=46419.msg514498#msg514498
>>> Doing the same idea, but using powers of 2 instead of 10:
Code: [Select]
((lambda (/ n code)
   (setq n 4)
   (while (< n 60000)
     (setq code 'l
           n (* n 2))
     (repeat (/ n 4) (setq code (cons 'cddddr (list code))))
     (repeat (rem n 4) (setq code (cons 'cdr (list code))))
     (eval
       (cons 'defun
             (cons (read (strcat "cd" (itoa n) "r"))
                   (cons '(l) (list code))))))))
 
(defun nthcdr (n l /)
  (repeat (/ n 65536) (setq l (cd65536r l)))
  (repeat (/ (setq n (rem n 65536)) 16384) (setq l (cd16384r l)))
  (repeat (/ (setq n (rem n 16384)) 1024) (setq l (cd1024r l)))
  (repeat (/ (setq n (rem n 1024)) 128) (setq l (cd128r l)))
  (repeat (/ (setq n (rem n 128)) 16) (setq l (cd16r l)))
  (repeat (/ (setq n (rem n 16)) 4) (setq l (cddddr l)))
  (repeat (rem n 4) (setq l (cdr l)))
  l)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: vl-position vs member
« Reply #9 on: May 02, 2015, 04:56:56 AM »
:nerdyembarassed: you are the third!    :)

http://www.theswamp.org/index.php?topic=46419.msg514498#msg514498
>>> Doing the same idea, but using powers of 2 instead of 10:
...
:lol: ... my therapy session must be starting soon ...

It's one of those ideas which I like very much about Lisp in general: The "meta-programming" which goes beyond most other programming languages' "macro" facilities. Strictly speaking AutoLisp isn't a "full" Lisp, but still it gives this "macro" ability which is usually lacking in something like C.

I.e. instead of writing all those functions by hand, using lots of copy-paste and manual edits (i.e. a great many chances of making mistakes) you use stuff like eval to write code which "writes" code  :-o. Of course it's not (yet) as powerful as those defmacro ideas in Common Lisp / Scheme, but it's "getting close"  :wink:
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

ymg

  • Guest
Re: vl-position vs member
« Reply #10 on: May 02, 2015, 09:41:18 AM »
Quote
(benchmark '((car (nthcdr 4995 l)) (car (member 4995 l)) (nth (vl-position 4995 l) l)))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

    (NTH (VL-POSITION 4995 L) L).....1700 / 5.47 <fastest>
    (CAR (NTHCDR 4995 L))............3947 / 2.36
    (CAR (MEMBER 4995 L))............9297 / 1.00 <slowest>

I guess I'm heading to the therapist too.

ymg

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: vl-position vs member
« Reply #11 on: May 02, 2015, 11:51:27 AM »
The thing is you're comparing apples with motor cars and air planes over there.

The vl-position returns the index of the found item which then is used in nth to return only that item. Member returns the found item and everything which follows it, which you then chop off to return only the first item from that list through car. NthCDR returns the n+1th item (not the found item) and everything following that,  again you chop off using car. So in both the later cases you already get the residual list (which is much more values passed around) and then you send that to another function to get rid of the extraneous portion. In such case nth + vl-position has an unfair advantage - and is probably the thing you should use (for such situation).

Looking at it from the other end: E.g. combining vl-position together with NthCDR would give you the same result as member does. So to actually compare these you'd do somthing like this instead:
Code - Auto/Visual Lisp: [Select]
  1. (benchmark '((nthcdr (vl-position 4995 l) l) (member 4995 l)))
« Last Edit: May 02, 2015, 11:58:45 AM 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: vl-position vs member
« Reply #12 on: May 02, 2015, 12:21:50 PM »
Quote
(benchmark '((car (nthcdr 4995 l)) (car (member 4995 l)) (nth (vl-position 4995 l) l)))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

    (NTH (VL-POSITION 4995 L) L).....1700 / 5.47 <fastest>
    (CAR (NTHCDR 4995 L))............3947 / 2.36
    (CAR (MEMBER 4995 L))............9297 / 1.00 <slowest>

I guess I'm heading to the therapist too.

ymg
Just to be a bit more clear ... and actually showing something which isn't very "useful": The nthcdr clause in your test produces a different result than the others (except if your list is simply a range of values from 0 through by incrementing each item to match its index).

E.g. another method which would outperform even that nth + vl-position, and yet still give the exact same result:
Code - Auto/Visual Lisp: [Select]
  1. (defun FindItem (item L)
  2.   (if (vl-position item L) item))

Or if you don't mind it still returning the value irrespective if it is actually inside the list or not ... then this would blow the socks off all those:
Code - Auto/Visual Lisp: [Select]
  1. (defun JustReturnItem (item L) item)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

ymg

  • Guest
Re: vl-position vs member
« Reply #13 on: May 02, 2015, 01:07:05 PM »
Irne,

Agree, the list was may be too simple.

Notheless,  look at the following:

Quote
$ (setq p (nth 4998 pl))
(4995.66 83.3284 14.6166)
_$ (benchmark '((car (nthcdr (vl-position p pl) pl)) (car (member p pl)) (nth (vl-position p pl) pl)))
Benchmarking ................Elapsed milliseconds / relative speed for 8192 iteration(s):

    (NTH (VL-POSITION P PL) PL)..............1685 / 3.21 <fastest>
    (CAR (NTHCDR (VL-POSITION P PL) PL)).....3151 / 1.72
    (CAR (MEMBER P PL))......................5413 / 1.00 <slowest>
_$ (NTH (VL-POSITION P PL) PL)
(4995.66 83.3284 14.6166)
_$ (CAR (NTHCDR (VL-POSITION P PL) PL))
(4995.66 83.3284 14.6166)
_$ (CAR (MEMBER P PL))
(4995.66 83.3284 14.6166)
_$

My point is I used the vl-position trick to get index in list.
Main use is to make sure a point is there or not.

ymg



« Last Edit: May 02, 2015, 01:10:26 PM by ymg »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: vl-position vs member
« Reply #14 on: May 02, 2015, 03:29:54 PM »
Quote
(benchmark '((car (nthcdr 4995 l)) (car (member 4995 l)) (nth (vl-position 4995 l) l)))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

    (NTH (VL-POSITION 4995 L) L).....1700 / 5.47 <fastest>
    (CAR (NTHCDR 4995 L))............3947 / 2.36
    (CAR (MEMBER 4995 L))............9297 / 1.00 <slowest>

I guess I'm heading to the therapist too.

ymg
Why do not you have tested even ALE_List_NthCdr?   :blink: