TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Kerry on June 22, 2010, 12:25:06 AM
-
Not really a challenge , but if you feel inclined .. :)
Anyone see a way to speed this routine up, based on the data provided ??
Essentially it's taking a point list and 'connecting the dots' with lines in the current UCS.
I tried an ActiveX solution but it's about 4.5 times slower.
Haven't looked at ARX or C# yet ....
DATA :
(setq vertexList1 (list (setq sp (list 0. 0. 0.))
(list 200. 0. 0.)
(list 200. 100. 0.)
(list 0. 100. 0.)
sp
)
layerName (getvar "CLAYER")
)
ROUTINE:
(defun test13 (vertexList layerName / TranslatedList DXF210)
;; Codehimbelonga kdub 2010.06.22
(setq TranslatedList (mapcar '(lambda (x) (trans x acucs acworld)) vertexList)
DXF210 (trans '(0 0 1) 1 0 T)
)
(foreach ptPair (mapcar (function (lambda (a b) (list a b)))
TranslatedList
(cdr TranslatedList)
)
(entmakex (list '(0 . "LINE")
'(100 . "AcDbLine")
(cons 8 layerName)
(cons 10 (car ptPair))
(cons 11 (cadr ptPair))
(cons 210 DXF210)
)
)
)
)
SOME OPTIONS :
(defun kdub:drawOneLineEn (sp ep la /)
;; Codehimbelonga kdub 2010.06.22
(entmakex (list '(0 . "LINE")
'(100 . "AcDbLine")
(cons 8 la)
(cons 10 (trans sp acucs acworld))
(cons 11 (trans ep acucs acworld))
(cons 210 (trans '(0 0 1) 1 0 T))
)
)
)
(defun test12 (vertexList layerName /)
;; Codehimbelonga kdub 2010.06.22
(foreach ptPair (mapcar (function (lambda (a b) (list a b)))
vertexList
(cdr vertexList)
)
(kdub:drawOneLineEn (car ptPair) (cadr ptPair) layerName)
)
)
Some TEST Results :
Benchmarking [M.P. 2005 < revised kdub 2005>] ...............
Elapsed milliseconds for 4096 iteration(s)/ relative Timing :
(TEST12 VERTEXLIST1 LAYERNAME).....1015 / 1.0150 <slowest>
(TEST13 VERTEXLIST1 LAYERNAME).....1000 / 1.0000 <fastest>
-
It MAY be faster to draw a LWPolyLine and explode it :-)
;;;---------------------------------------------------------------------------
;;;
;;; (setq vertexList (list (list 0. 0. 0.)
;;; (list 200. 0. 0.)
;;; (list 200. 100. 0.)
;;; (list 0. 100. 0.)
;;; )
;;; layerName (getvar "CLAYER")
;;; )
;;; (kbub:drawEnPlineInUCS vertexList layerName 1)
;; vertexList points expressed in Current UCS
(defun kbub:drawEnPlineInUCS (vertexList layerName putClosed / DXF210 elev)
;; Codehimbelonga kdub 2010.06.22
(setq DXF210 (trans '(0 0 1) 1 0 T))
(entmakex
(append (list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length vertexList))
(cons 70 putClosed) ; 1 closed : 0 open
(cons 8 layerName)
(cons 38 (caddr (trans (car vertexList) 1 DXF210)))
(cons 210 DXF210)
)
(mapcar '(lambda (pt) (cons 10 (trans pt 1 DXF210))) vertexList)
)
)
)
;;;---------------------------------------------------------------------------
;;;
Benchmarking [M.P. 2005 < revised kdub 2005>] ................
Elapsed milliseconds for 8192 iteration(s)/ relative Timing :
(TEST12 VERTEXLIST1 LAYERNAME)...............2047 / 1.9257 <slowest>
(TEST13 VERTEXLIST1 LAYERNAME)...............2016 / 1.8965
(KBUB:DRAWENPLINEINUCS VERTEXLIST LA...).....1063 / 1.0000 <fastest>
-
just a note on this ;
Benchmarking [M.P. 2005 < revised kdub 2005>] ................
Elapsed milliseconds for 8192 iteration(s)/ relative Timing :
(TEST12 VERTEXLIST1 LAYERNAME)...............2047 / 1.9257 <slowest>
(TEST13 VERTEXLIST1 LAYERNAME)...............2016 / 1.8965
(KBUB:DRAWENPLINEINUCS VERTEXLIST LA...).....1063 / 1.0000 <fastest>
The output is different to MP's original routine.
The fastest expression has been given a index of 1.
Subsequent expressions are shown with an index proportional to the time taken.
ie in this case Test12 takes 1.92 times longer to run than kbub:drawEnPlineInUCS.
Hope this doesn't cause confusion.
-
I also could not draw a lot of lines faster than explode polyline! :-)
my test (acad 2008 sp2):
(defun kbub:drawEnPlineInUCS (vertexList layerName putClosed / DXF210 elev)
;; Codehimbelonga kdub 2010.06.22
(setq DXF210 (trans '(0 0 1) 1 0 T))
(entmakex (append (list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length vertexList))
(cons 70 putClosed) ; 1 closed : 0 open
(cons 8 layerName)
(cons 38 (caddr (trans (car vertexList) 1 DXF210)))
(cons 210 DXF210)
) ;_ list
(mapcar '(lambda (pt) (cons 10 (trans pt 1 DXF210))) vertexList)
) ;_ append
) ;_ entmakex
) ;_ defun
(defun test_5 (l n c)
(if (setq l (kbub:drawEnPlineInUCS l n c))
(progn (vla-explode (vlax-ename->vla-object l)) (entdel l))
) ;_ if
) ;_ defun
(defun kdub:drawOneLineEn (sp ep la /)
;; Codehimbelonga kdub 2010.06.22
(entmakex (list '(0 . "LINE")
'(100 . "AcDbLine")
(cons 8 la)
(cons 10 (trans sp acucs acworld))
(cons 11 (trans ep acucs acworld))
(cons 210 (trans '(0 0 1) 1 0 T))
) ;_ list
) ;_ entmakex
) ;_ defun
(defun test12 (vertexList layerName /)
;; Codehimbelonga kdub 2010.06.22
(foreach ptPair
(mapcar (function (lambda (a b) (list a b))) vertexList (cdr vertexList))
(kdub:drawOneLineEn (car ptPair) (cadr ptPair) layerName)
) ;_ foreach
) ;_ defun
(defun test_6 ( l n /)
(mapcar (function (lambda (a b)
(entmakex (list '(0 . "LINE")
'(100 . "AcDbLine")
(cons 8 n)
(cons 10 (trans a acucs acworld))
(cons 11 (trans b acucs acworld))
(cons 210 (trans '(0 0 1) acucs acworld T))
) ;_ list
) ;_ entmakex
) ;_ lambda
) ;_ function
l
(cdr l)
) ;_ mapcar
) ;_ defun
(defun test_7 (l n / v)
(setq l (mapcar '(lambda (a) (trans a 1 0)) l)
n (cons 8 n)
v (cons 210 (trans '(0 0 1) 1 0 T))
) ;_ setq
(mapcar
(function (lambda (a b) (entmakex (list '(0 . "LINE") n (cons 10 a) (cons 11 b) v))))
l
(cdr l)
) ;_ mapcar
) ;_ defun
;;;;;;;;;;;;;;;;;;;;;;;;;
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 1
) ;_ setq
(mapcar
(function (lambda (a) (repeat 1 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test12 l n) (test_5 l n c)(test_6 l n)(test_7 l n)))
;;;;
Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s):
(TEST_6 L N).......1078 / 1.62 <fastest>
(TEST_7 L N).......1078 / 1.62
(TEST12 L N).......1125 / 1.56
(TEST_5 L N C).....1750 / 1.00 <slowest>
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 1
) ;_ setq
(mapcar
(function (lambda (a) (repeat 10 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test12 l n) (test_5 l n c)(test_6 l n)(test_7 l n)))
;;;;
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):
(TEST_5 L N C).....1672 / 1.38 <fastest>
(TEST_7 L N).......2110 / 1.10
(TEST_6 L N).......2234 / 1.04
(TEST12 L N).......2313 / 1.00 <slowest>
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 1
) ;_ setq
(mapcar
(function (lambda (a) (repeat 100 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test12 l n) (test_5 l n c) (test_6 l n) (test_7 l n)))
;;;;
Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
(TEST_5 L N C).....2093 / 2.12 <fastest>
(TEST_7 L N).......3890 / 1.14
(TEST_6 L N).......4203 / 1.06
(TEST12 L N).......4438 / 1.00 <slowest>
;;;;;;;;;;;;;;;;;;;;;;;;;
-
Perhaps:
(defun LM_poly ( l / n p )
(setq n (trans '(0. 0. 1.) 1 0 t)
p (list (cons 10 (trans (car l) 1 n))))
(while (setq l (cdr l))
(setq p (cons (cons 10 (trans (car l) 1 n)) p))
)
(entmakex (append (list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length p))
(cons 70 1)
(cons 38 (cadddr (car p)))
(cons 210 n)
)
p
)
)
)
(defun LM_test ( l / p )
(if (setq p (LM_poly l))
(progn
(vla-Explode (vlax-ename->vla-object p))
(entdel p)
)
)
(princ)
)
-
Perhaps:
(defun LM_poly ( l / n p )
;;.......
It MAY be faster to draw a LWPolyLine and explode it :-)
..
(defun kbub:drawEnPlineInUCS (vertexList layerName putClosed / DXF210 elev)
;; < .. >
I also could not draw a lot of lines faster than explode polyline! :-)
Yes, that's been covered Lee :-D
-
Yes, that's been covered Lee :-D
I thought that the way the list was constructed may be faster is all - I did read the thread... :roll:
-
Yes, that's been covered Lee :-D
I thought that the way the list was constructed may be faster is all - I did read the thread... :roll:
I can't see a while, 2 con's and 2 setq's being faster ... but would be interested in seeing a test if you think it may be faster ..
I'm at home with a bottle of red at the moment, don't feel like writing code :)
-
Doesn't trans and entmake(x) go through the ADS interface? If they do then that's a bottleneck there.
-
Doesn't trans and entmake(x) go through the ADS interface? If they do then that's a bottleneck there.
entmake is about 4.5 times faster than ActiveX Paul.
and the option to trans is writing our own translator .. :)
The code I posted is actually pretty fast, just looking for alternatives.
-
Doesn't trans and entmake(x) go through the ADS interface? If they do then that's a bottleneck there.
entmake is about 4.5 times faster than ActiveX Paul.
and the option to trans is writing our own translator .. :)
The code I posted is actually pretty fast, just looking for alternatives.
Didn't know that about the activex, was thinking...um wasn't really.. :-D
-
Kerry, in your test13 you used this
(setq TranslatedList (mapcar '(lambda (x)
but this should be faster
(setq TranslatedList (mapcar (function (lambda (x)
and WHILE is faster than foreach :-)
-
Hi Kerry,
Just curious. Is this, "entmake is about 4.5 times faster than ActiveX" a blanket statement or does it just apply to this topic?
My experience/testing with creating objects with entmake vs ActiveX indicates they are in general about the same speedwise. Of course I might be wrong.
-
May show some improvement, no time to test this morning. Later 8-)
(defun test13cab (vertexList layerName / TranslatedList DXF210)
;; Codehimbelonga kdub 2010.06.22
(setq TranslatedList (mapcar (function (lambda (x) (trans x acucs acworld))) vertexList)
DXF210 (trans '(0 0 1) 1 0 T)
)
(setq PairLst (mapcar (function (lambda (a b) (list a b)))
TranslatedList
(cdr TranslatedList)
)
(while (setq ptPair (car PaitLst))
(setq PairLst (cdr PairLst))
(entmakex (list '(0 . "LINE")
'(100 . "AcDbLine")
(cons 8 layerName)
(cons 10 (car ptPair))
(cons 11 (cadr ptPair))
(cons 210 DXF210)
)
)
)
)
-
Hi Kerry,
Just curious. Is this, "entmake is about 4.5 times faster than ActiveX" a blanket statement or does it just apply to this topic?
My experience/testing with creating objects with entmake vs ActiveX indicates they are in general about the same speedwise. Of course I might be wrong.
Just to this Joe ... don't have the code handy but my tests ranged between 3.8 and 4.5 times
... perhaps the code could have been optimised but didn't seem worth it.
-
Kerry, in your test13 you used this
(setq TranslatedList (mapcar '(lambda (x)
but this should be faster
(setq TranslatedList (mapcar (function (lambda (x)
and WHILE is faster than foreach :-)
Thanks Alan, I'll have a play tomorrow.
Thanks guys !!!
-
new version, use VLA-*
(defun test_8 (l n c)
;;(test_8 l n)
(setq v (trans '(0 0 1) 1 0 T)
a (vla-addLightWeightPolyline
(vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
(vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray '5 (cons 0 (1- (* (length l) 2))))
(apply (function append)
(mapcar '(lambda (a) ((lambda (a) (list (car a) (cadr a))) (trans a 1 v))) l)
) ;_ apply
) ;_ vlax-safearray-fill
) ;_ vlax-make-variant
) ;_ vla-addLightWeightPolyline
) ;_ setq
(vla-put-layer a n)
(vla-put-normal a (vlax-3d-point v))
(vla-put-closed a (if (zerop c) :vlax-false :vlax-true))
(vla-put-elevation a (caddr (trans (car l) 1 v)))
(vla-explode a)
(vla-delete a)
) ;_ defun
(defun kbub:drawEnPlineInUCS (vertexList layerName putClosed / DXF210 elev)
;; Codehimbelonga kdub 2010.06.22
(setq DXF210 (trans '(0 0 1) 1 0 T))
(entmakex (append (list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length vertexList))
(cons 70 putClosed) ; 1 closed : 0 open
(cons 8 layerName)
(cons 38 (caddr (trans (car vertexList) 1 DXF210)))
(cons 210 DXF210)
) ;_ list
(mapcar '(lambda (pt) (cons 10 (trans pt 1 DXF210))) vertexList)
) ;_ append
) ;_ entmakex
) ;_ defun
(defun test_5 (l n c)
(if (setq l (kbub:drawEnPlineInUCS l n c))
(progn (vla-explode (vlax-ename->vla-object l)) (entdel l))
) ;_ if
) ;_ defun
(length l) = 5
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 0
) ;_ setq
(mapcar
(function (lambda (a) (repeat 1 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test_5 l n c) (test_8 l n c)))
;;------------------------------
Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s):
(TEST_5 L N C).....1516 / 1.48 <fastest>
(TEST_8 L N C).....2250 / 1.00 <slowest>
(length l) = 41
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 0
) ;_ setq
(mapcar
(function (lambda (a) (repeat 10 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test_5 l n c) (test_8 l n c)))
;;------------------------------
Benchmarking ............Elapsed milliseconds / relative speed for 512 iteration(s):
(TEST_5 L N C).....1141 / 1.06 <fastest>
(TEST_8 L N C).....1204 / 1.00 <slowest>
(length l) = 201
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 0
) ;_ setq
(mapcar
(function (lambda (a) (repeat 50 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test_5 l n c) (test_8 l n c)))
;;------------------------------
Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
(TEST_8 L N C).....1078 / 1.29 <fastest>
(TEST_5 L N C).....1391 / 1.00 <slowest>
(length l) = 2001
(progn
(setq l '((0 0 0))
n (getvar "CLAYER")
c 0
) ;_ setq
(mapcar
(function (lambda (a) (repeat 500 (setq l (cons (mapcar (function +) a (car l)) l)))))
'((1 0 0) (0 1 0) (-1 0 0) (0 -1 0))
) ;_ mapcar
) ;_ progn
(BenchMark '((test_5 l n c) (test_8 l n c)))
;;------------------------------
Benchmarking .......Elapsed milliseconds / relative speed for 16 iteration(s):
(TEST_8 L N C).....1297 / 1.33 <fastest>
(TEST_5 L N C).....1719 / 1.00 <slowest>
-
Thanks Evgeniy , that's a lot better than I was getting out of ActiveX
... I'll check my code tomorrow, but I think it will slows down when faced with a lot of single lines :)
yes, I think exploding a lwpline may be the way to go.
The improvement with larger lists sort of makes sense.
-
Thanks Evgeniy , that's a lot better than I was getting out of ActiveX ... I'll check my code tomorrow :)
The improvement with larger lists sort of makes sense.
How long lists will be used - 100, 1000 or 10000? For a very long list, you can make an additional optimization.
-
I think you can create a polyline with the current set of points, then transform it to explode
-
< .. >
How long lists will be used - 100, 1000 or 10000? For a very long list, you can make an additional optimization.
varies from 2 to say 50 .. usually about 12 ; for the use I have in mind at the moment