Author Topic: Speeding up a function  (Read 1282 times)

0 Members and 1 Guest are viewing this topic.

S.Langhammer

  • Guest
Speeding up a function
« on: May 14, 2013, 03:28:21 AM »
Hello again!

I'm working on an interface to read out filtered entity information from .dwg files via BricsCAD (using AutoLISP) and a Delphi component.
When I was assigned to this project I had no idea about LISP  but with lots of code examples, tutorials and the great help from you guys here, I improved a lot and now the LISP script does exactly what it'S supposed to do.
Now I'm looking around to see if I can Speed my script up and simpliefy it. I'm doing my best, researching and refactoring, but I'm still rather un experienced so I'm asking here, if anyone of you sees possibilities to help me speed my script up. Every saved operation helps.
The following functions cought my attention first, since they are together one of the largest chunks of code in the entire script.

Some info first:
- The variable "step" Comes from the function, which calls getPolData and containes the -1 dxf information of the current entity. I reuse it within getPolData, so I don't have to make another variable.
-I set variables Nil, because I've red somewhere, that that speeds LISP up somehow. I can't recall where I red that tho.

Code - Auto/Visual Lisp: [Select]
  1. (defun vertexValues ()
  2.         (if (> WCSFla 0);;; Point value
  3.                 ;THEN
  4.                 (setq pt (cdr(assoc 10 enLst)));;; 3D-Polyline
  5.                 ;ELSE
  6.                 (setq pt (trans (cdr(assoc 10 enLst)) entNorm 0));;; 2D-Polyline
  7.         )
  8.         (setq PtStr(strcat (rtos(car pt)2 4)spcr(rtos(cadr pt)2 4)spcr(rtos(caddr pt)2 4)));;; -> to string
  9.        
  10.         (if (setq verInd1 (cdr(assoc 71 enLst)));;; Polyfacemesh vertex index 1
  11.                 ;THEN
  12.                 (setq verInd1 (abs verInd1)
  13.                           verIndChk verInd1
  14.                           verInd1(itoa verInd1)
  15.                 )
  16.                 ;ELSE
  17.                 (setq verInd1  "0"
  18.                           verIndChk 0
  19.                 )
  20.         )
  21.         (if (setq verInd2 (cdr(assoc 72 enLst)));;; Polyfacemesh vertex index 2
  22.                 ;THEN
  23.                 (setq verInd2(itoa(abs verInd2)))
  24.                 ;ELSE
  25.                 (setq verInd2 "0")
  26.         )
  27.         (if (setq verInd3 (cdr(assoc 73 enLst)));;; Polyfacemesh vertex index 3
  28.                 ;THEN
  29.                 (setq verInd3(itoa(abs verInd3)))
  30.                 ;ELSE
  31.                 (setq verInd3 "0")
  32.         )
  33.         (if (setq verInd4 (cdr(assoc 74 enLst)));;; Polyfacemesh vertex index 4
  34.                 ;THEN
  35.                 (setq verInd4(itoa(abs verInd4)))
  36.                 ;ELSE
  37.                 (setq verInd4 "0")
  38.         )
  39. )       ;;; end vertexValues
  40. ;;;
  41.  
  42.  
  43. (defun getPolData(/ entLyr ptLst enLst entFla entFlaStr entNorm pt verInd1 verInd2 verInd3 verInd4 faceFla WCSFla verIndChk 1PtStr)
  44.         (setq entLyr            (cdr(assoc   8 entity));;; Layer
  45.                   entNorm               (cdr(assoc 210 entity));;; Normal-/Extrusion vector
  46.                   step                  (entnext step);;; name of the first verte
  47.                   enLst                 (entget  step);;; -> dxf groupcode
  48.                   faceFla               0
  49.                   WCSFla                0;;; flag: OCS (0) oder WCS (1)
  50.         )
  51.         (if (and (setq entFlaStr "0" entFla(cdr(assoc 70 entity))) (> entFla 0));;; Flag, Polylinientype  0 = default, open Polylinie
  52.         (progn
  53.                 (if (>= entFla 128)     ;;; 128 ignored
  54.                         (setq entFla(- entFla 128))
  55.                 )
  56.                 (if (>= entFla 64);;; 64 = Polyface Mesh
  57.                         (setq entFla(- entFla  64)
  58.                                   entFlaStr "64"
  59.                                   WCSFla 1 ;;; WCS
  60.                         )
  61.                 )
  62.                 (if (>= entFla 32);;; 32 ignored
  63.                         (setq entFla(- entFla  32))
  64.                 )
  65.                 (if (>= entFla 16);;; 16 = 3D Polygon Mesh
  66.                         (setq entFla(- entFla  16)
  67.                                   entFlaStr "16"
  68.                         )
  69.                 )
  70.                 (if (>= entFla 8);;; 8 = 3D Polylinie
  71.                         (setq entFla(- entFla  8)
  72.                                   WCSFla 1 ;;; WCS
  73.                         )
  74.                 )
  75.                 (if (>= entFla 4);;; 4  ignored
  76.                         (setq entFla(- entFla  4))
  77.                 )
  78.                 (if (>= entFla 2);;; 2 ignored
  79.                         (setq entFla(- entFla  2))
  80.                 )
  81.                 (if (and (>= entFla 1) (not(or (= entFlaStr "16") (= entFlaStr "64"))));;; 1 closed Polyline
  82.                         (setq entFlaStr "1")
  83.                 )
  84.         );end progn
  85.         )       ;;;end Flag-If
  86.        
  87.         entity  nil
  88.         (if (/= entFlaStr "16");;; Polyface Meshes are being skipped in this function
  89.         (progn
  90.                 (if (= entFlaStr "1");;; closed Polyline case
  91.                 (progn ;;; the first point is saved in a temporary string
  92.                         (vertexValues)
  93.                         (setq 1PtStr (strcat ptStr spcr verInd1 spcr verInd2 spcr verInd3 spcr verInd4 "\n"));;; temporary saved first point
  94.                 );end progn
  95.                 )       ;;; end if - closed Polylinie
  96.                 (while (and (/= (cdr(assoc 0 enLst))"SEQEND") (/= 16 (cdr(assoc 70 enLst))));;; while the current following entity is a vertex, but not a spline frame control point
  97.                         (vertexValues)
  98.                         (if (and                        ;;; mark the beginning of the face sets
  99.                                         (or (= PtStr "0,0,0")(= PtStr "0.0000,0.0000,0.0000"))
  100.                                         (>= verIndChk 1)
  101.                                         (< faceFla 1)
  102.                                 )
  103.                                 (setq ptLst(cons "FACES:\n" ptLst)
  104.                                           faceFla 1
  105.                                 )
  106.                         )
  107.                         (setq ptLst(cons (strcat ptStr spcr verInd1 spcr verInd2 spcr verInd3 spcr verInd4 "\n") ptLst);;; adding the point/face to the list
  108.                                  
  109.                                   step          (entnext step);;; get next subentity name
  110.                                   enLst         (entget  step);;; get the group codes
  111.                                  
  112.                                   ptStr         nil ;;; free ram
  113.                                   verInd1       nil
  114.                                   verInd2       nil
  115.                                   verInd3       nil
  116.                                   verInd4       nil
  117.                                   pt            nil
  118.                         )
  119.                 )       ;;; end while vertex
  120.                 (if (= entFlaStr "1") ;;; closed polyline case
  121.                         (setq ptLst(cons 1PtStr ptLst)
  122.                                   1PtStr nil
  123.                         )
  124.                 )
  125.                 (setq enLst             nil ;;; free ram
  126.                           step          nil
  127.                           faceFla       nil
  128.                           entFla        nil
  129.                           verIndChk     nil
  130.                           WCSFla        nil
  131.                          
  132.                           entNorm       (strcat (rtos(car entNorm)2 4)spcr(rtos(cadr entNorm)2 4)spcr(rtos(caddr entNorm)2 4)) ;;; -> normal vector to string
  133.                 )
  134.                 (fileWrite (strcat "POLYLINE" spcr entLyr spcr entFlaStr spcr entNorm "\n")) ;;; writes the header of the entity to the file
  135.                 ;;; 0 . Entitätentyp
  136.                 ;;; 1 . Layer
  137.                 ;;; 2 . Flag
  138.                 ;;; 3;4;5 . Normale
  139.                 (fileWrite (apply 'strcat (reverse ptLst))) ;;; writes the vertices to the file
  140.         );end Progn
  141.         )       ;;; end Polyfacemesh-Ausschluss
  142.         (setq entLyr    nil ;;; free ram
  143.                   entNorm       nil
  144.                   ptLst         nil
  145.                   entFlaStr     nil
  146.         )
  147.         (princ)
  148. )       ;;; end getPolData
  149. ;;; max list index 5
  150.  

As always thanks for the help!

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Speeding up a function
« Reply #1 on: May 14, 2013, 02:31:06 PM »
Some remarks:

1.
This:
Code - Auto/Visual Lisp: [Select]
  1. (if (>= entFla 128) ; 128 ignored
  2.   (setq entFla (- entFla 128))
  3. )
  4. (if (>= entFla 32) ; 32 ignored
  5.   (setq entFla (- entFla  32))
  6. )
  7. (if (>= entFla 4) ; 4  ignored
  8.   (setq entFla (- entFla  4))
  9. )
  10. (if (>= entFla 2) ; 2 ignored
  11.   (setq entFla (- entFla  2))
  12. )
Achieves the same as:
Code - Auto/Visual Lisp: [Select]
  1. (setq entFla (logand entFla (~ 166))) ; 166 = 128+32+4+2

2.
Memory management is largely handled automatically by the Lisp-engine.
You can force a garbage collection by using:
Code - Auto/Visual Lisp: [Select]
  1. (gc)
But for local variables I would not use:
Code - Auto/Visual Lisp: [Select]
  1. (setq var nil)
There is no reason for this and (setq) will only cost time. Especially when repeated inside a while loop.

3.
This:
Code - Auto/Visual Lisp: [Select]
  1. (if (setq verInd2 (cdr (assoc 72 enLst)))
  2.   (setq verInd2(itoa(abs verInd2)))
  3.   (setq verInd2 "0")
  4. )
Can be replaced by:
Code - Auto/Visual Lisp: [Select]
  1. (setq verInd2
  2.   (itoa
  3.     (abs
  4.       (cond
  5.         ( (cdr (assoc 72 enLst))
  6.         )
  7.         ( 0
  8.         )
  9.       )
  10.     )
  11.   )
  12. )
Which has fewer calls to (setq).

4.
Try reducing the number of write operations by combining them even more than you are already doing.