Author Topic: vLISP vs VBA performance gap  (Read 9386 times)

0 Members and 1 Guest are viewing this topic.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: vLISP vs VBA performance gap
« Reply #15 on: May 25, 2007, 10:35:30 AM »
<Quick2>Hi Chuck, some quick code to muse --

Code: [Select]
(defun c:DeleteEmptyText ( / ss count i )

    (StartUndo)
   
    (setq count 0)

    (if (setq ss (ssget "x" '((0 . "text,mtext")(1 . ", ,\\A1;"))))
        (repeat (setq i (sslength ss))
            ;;  trap unsuccessful deletion because
            ;;  object is on a locked layer
            (if (entdel (ssname ss (setq i (1- i))))
                (setq count (1+ count))
            )                                   
        )
    )
   
    (princ
        (strcat
            (itoa count)
            " blank text entity(s) erased."
        )
    )
   
    (EndUndo)
   
    (princ)
   
)

Edit: Revised to reflect entdel on a layer locked entity doesn't chuck a wobbly, just doesn't result in successful deletion.

Cheers and hi all.</Quick2>
« Last Edit: May 25, 2007, 10:56:42 AM by MP »
Engineering Technologist CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com http://cadanalyst.slack.com http://linkedin.com/in/cadanalyst

Chuck Gabriel

  • Guest
Re: vLISP vs VBA performance gap
« Reply #16 on: May 25, 2007, 10:58:29 AM »
Thanks MP.

I never considered (and didn't pick up on it in ronjonp's post) that you could provide a comma-delimited list of string values for group code 1 in the filter.  I routinely do that for group code 0, but for some reason it didn't click that I could apply the same technique in other ways.  Also, I think I'll incorporate a vl-catch-all-apply to trap unexpected errors like you did above.

I decided to only filter for entity type, and then manually examine the textstring values, so that I could catch lines of text consisting of an arbitrary number of spaces.

Thanks again for all the support everybody.

Oh yeah.  Also, thanks CAB for showing me that wildcards can be used in filter criteria.  I don't believe I've ever seen that trick before.
« Last Edit: May 25, 2007, 11:01:50 AM by Chuck Gabriel »

T.Willey

  • Needs a day job
  • Posts: 5251
Re: vLISP vs VBA performance gap
« Reply #17 on: May 25, 2007, 11:06:03 AM »
If you wanted to go the ActiveX way with lisp, and only wanted items of text within the spaces (tabs) like you get with 'ssget', then I would have coded it differently.  I would use this
Code: [Select]
(vlax-for Lo (vla-get-Layouts *ThisDrawing*)
 (vlax-for Obj (vla-get-Block Lo)
   .......
  )
)
I think this way is better because I have had problems (and has been pointed out by others) with trying to use 'entdel' on objects in other spaces than the one calling the routine.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Chuck Gabriel

  • Guest
Re: vLISP vs VBA performance gap
« Reply #18 on: May 25, 2007, 11:22:06 AM »
If you wanted to go the ActiveX way with lisp, and only wanted items of text within the spaces (tabs) like you get with 'ssget', then I would have coded it differently.  I would use this
Code: [Select]
(vlax-for Lo (vla-get-Layouts *ThisDrawing*)
 (vlax-for Obj (vla-get-Block Lo)
   .......
  )
)
I think this way is better because I have had problems (and has been pointed out by others) with trying to use 'entdel' on objects in other spaces than the one calling the routine.

That would certainly cut down on the amount of iteration required.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: vLISP vs VBA performance gap
« Reply #19 on: May 25, 2007, 11:28:45 AM »
If you were going activex, a quick bash ...

Code: [Select]
(defun c:DeleteEmptyText ( / count )

    (StartUndo)
   
    (setq count 0)
   
    (vlax-for layout
   
        (vlax-get
            (vlax-get
                (vlax-get-acad-object)
                'ActiveDocument
            )
           'Layouts
        )
   
        (vlax-for object (vlax-get layout 'Block)
       
            (if
           
                (and
                    (wcmatch
                        (vlax-get object 'ObjectName)
                        "AcDbText,AcDbMText"
                    )
                    (wcmatch
                        (vlax-get object 'TextString)
                        ", ,\\A1;"
                    )
                )   
               
                ;;  here we do have to trap an error
                ;;  unless we've unlocked all layers
                ;;  prior to running the routine
               
                (vl-catch-all-apply
                   '(lambda ( )
                        (vlax-invoke object 'Delete)
                        (setq count (1+ count))
                    )
                )
            )
        )
    )   

    (princ
        (strcat
            (itoa count)
            " empty text entities erased."
        )
    )
   
    (EndUndo)
   
    (princ)
   
)

Untested but should work. To answer the inevitable "Why vlax versus vla?" question in advance, I found when doing objectdbx stuff way back that on average vlax calls executed faster than equivalent vla calls. How much I don't recall, but it was enough to make me use the former in code that does a lot of iteration through collections et al.
Engineering Technologist CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com http://cadanalyst.slack.com http://linkedin.com/in/cadanalyst

Patrick_35

  • Guest
Re: vLISP vs VBA performance gap
« Reply #20 on: May 25, 2007, 11:32:17 AM »
By taking again the filter MP's selection

Code: [Select]
(defun c:DeleteEmptyText(/ sel)
  (if (ssget "x" '((0 . "text,mtext")(1 . ", ,\\A1;")))
    (progn
      (vla-erase (setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))))
      (vla-delete sel)
    )
  )
)

@+

T.Willey

  • Needs a day job
  • Posts: 5251
Re: vLISP vs VBA performance gap
« Reply #21 on: May 25, 2007, 11:34:44 AM »
<snip>
Untested but should work. To answer the inevitable "Why vlax versus vla?" question in advance, I found when doing objectdbx stuff way back that on average vlax calls executed faster than equivalent vla calls. How much I don't recall, but it was enough to make me use the former in code that does a lot of iteration through collections et al.
Thanks for this little tidbit Michael.  I never knew that one.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: vLISP vs VBA performance gap
« Reply #22 on: May 25, 2007, 11:38:24 AM »
By taking again the filter MP's selection ...

For the record I think it was Mr. Tanzillo who first revealed the succinct filter string of  ", " for nabbing null text.

I like the compact code Patrick but I'd guess it will crash if any null text entities reside on locked layers.

=)
Engineering Technologist CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com http://cadanalyst.slack.com http://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: vLISP vs VBA performance gap
« Reply #23 on: May 25, 2007, 11:39:52 AM »
Thanks for this little tidbit Michael.  I never knew that one.

You're very welcome Tim. If I know you you're testing the claim right now.

:lmao:
Engineering Technologist CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com http://cadanalyst.slack.com http://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Re: vLISP vs VBA performance gap
« Reply #24 on: May 25, 2007, 11:46:20 AM »
Very cool thread guys!!
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Patrick_35

  • Guest
Re: vLISP vs VBA performance gap
« Reply #25 on: May 25, 2007, 11:48:04 AM »
Quote
I like the compact code Patrick but I'd guess it will crash if any null text entities reside on locked layers.
*
Yes, exactly
A corrected version

Code: [Select]
(defun c:DeleteEmptyText(/ sel)
  (if (ssget "x" '((0 . "text,mtext")(1 . ", ,\\A1;")))
    (progn
      (vlax-map-collection (setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))) '(lambda (x) (vl-catch-all-apply 'vla-delete (list x))))
      (vla-delete sel)
    )
  )
)

@+

T.Willey

  • Needs a day job
  • Posts: 5251
Re: vLISP vs VBA performance gap
« Reply #26 on: May 25, 2007, 12:09:02 PM »
Thanks for this little tidbit Michael.  I never knew that one.

You're very welcome Tim. If I know you you're testing the claim right now.

:lmao:
Nothing to see here, move along.  :roll:
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vLISP vs VBA performance gap
« Reply #27 on: May 25, 2007, 01:04:37 PM »
One more version:
Code: [Select]
(defun c:DeleteEmptyText (/ ss)
  (and
    (setq ss (ssget "x" '((0 . "text,mtext") (1 . ", ,\\A1;"))))
    (mapcar '(lambda (x) (vl-catch-all-apply 'vla-delete
                         (list (vlax-ename->vla-object x))))
          (mapcar 'cadr (ssnamex ss)))
  )
)
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.

Chuck Gabriel

  • Guest
Re: vLISP vs VBA performance gap
« Reply #28 on: May 25, 2007, 01:20:15 PM »
Wow!  That is one thoroughly skinned cat!

I didn't realize the true power of ", " when I first saw it.  I thought it would grab null strings and strings with a value of " ", but it will actually grab any string that is either null or made entirely of spaces.  That is awesome!

This really has been a great thread.  I've learned a lot.  Thanks again everybody.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: vLISP vs VBA performance gap
« Reply #29 on: May 25, 2007, 01:28:38 PM »
re: ", " ... as noted previously, another great tip you can attribute to Tony.

re: Error trapping the attempt to delete on an entity by entity basis can yield a significant performance hit. An alternative is to delete only those (matching) entities that reside on unlocked layers (quick knock off):

Code: [Select]
(defun c:DeleteEmptyText ( / count doc selection )

    (setq count 0)

    (vlax-for layer
   
        (vlax-get
            (setq doc (vlax-get (vlax-get-acad-object) 'ActiveDocument))
           'Layers
        )
       
        (if
            (and
                (zerop (vlax-get layer 'Lock))
                (ssget "x"
                    (list
                       '(0 . "text,mtext")
                       '(1 . ", ,\\A1;")
                        (cons 8 (vlax-get layer 'Name))
                    )
                )
            )
            (progn
                (setq count
                    (+ count
                        (vla-get-count
                            (setq selection
                                (vlax-get doc 'ActiveSelectionset)
                            )
                        )
                    )       
                )
                (vlax-invoke selection 'Erase)
                (vlax-invoke selection 'Delete)
            )   
        )
    )
   
    (princ
        (strcat
            (itoa count)
            " empty text entity(s) erased."
        )
    )
   
    (princ)

)

Subtitle: Smaller isn't always better.

:)
« Last Edit: May 25, 2007, 01:55:05 PM by MP »
Engineering Technologist CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.com http://cadanalyst.slack.com http://linkedin.com/in/cadanalyst