Speed Test - Drawing 1000 and 10000 Solid3D Boxes using different Methods

Hi all,
I compared the speed of 4 different methods to create randomly solid3d primitives (entities),
using in this test a solid3D BOX object. Four different methods are used in a lisp file :

   1. The command processor... using the command BOX in the command line
        (vl-cmdf "_BOX" currentP1 currentP2)
   2. The COM-Lisp interface (vl-load-com)
        (vla-addbox Mspace (vlax-3d-point BoxCenterPT) (abs BoxL) (abs BoxW) (abs BoxH))
   3. A Lispfunction programmed in C# .NET
       (CreateSolidBOX currentP1 currentP2)
   4.  The native Lisp Function entmake
        (entmake   solBoxBCAD-entityList) 

     CP,  COM,  C#,  LISP  are used for 1, 2, 3, 4  in the table below respectively.
         The results are as follows :

!! ALL NUMBERS are in seconds !!    
No. of
Attempts  CP     COM    C#.NET   Lisp
-----------------------------------------------------------------------------------------
    Creating   1000   Solid3D  Boxes in Bricscad  12.2.14-1  32bit
-----------------------------------------------------------------------------------------        
1st     2,09       1,08        1,22       1,51
2nd    2,15       1,06        1,15       1,48
3rd     2,23       1,08        1,15       1,5
4th     2,48       1,09        1,21       1,53
-----------------------------------------------------------------------------------------                
Creating   10000    Solid3D  Boxes in Bricscad  12.2.14-1    32bit
-----------------------------------------------------------------------------------------
1st     51,92     10,58      11,42     14,79
2nd    55,04     10,1        11,69     15,19
-----------------------------------------------------------------------------------------                
    Creating   1000   Solid3D  Boxes in   "BIG-APPLE…"   2012   64bit
-----------------------------------------------------------------------------------------    
1st     7,94        2,4          2,6        3,9
2nd    7,79       2,48         2,6        3,96
-------------------------------------------------------------------------------------------                
    Creating   10000   Solid3D  Boxes in   "BIG-APPLE…"   2012  64bit
-------------------------------------------------------------------------------------------        
1st     94,86     25,15       29,06    44,21
2nd    87,98     27,75       31,77    45,69

COM seems to be the winner ...!
It would be interesting if one could test BRX using a C++ function to create a BOX ???
The test was done on a Intel Core(TM)2 Duo CPU E8300 @ 2.83 GHz  RAM  8,0  GB  computer, running WIN7 64 bit.
I wanted to share the results with you !

Comments

  • In my tests (vla-add) works faster than (entmake) too.

    Regards, Vaidas
  • Interesting, but may be Apples and Oranges though.. There is a bit of overhead passing lisp arguments to .NET.  as it has to be translated into a resbuf (BRX) then to a.NET ResultBuffer. The ResultBuffer class in itself is a monster, it has to thunk between managed and unmanaged memory and each argument also has to be translated be to a .NET TypedValue.  I'm surprised it did that well : ) Go with strait C# and I bet it will perform much better.

    [code]

    using System;
    using System.Diagnostics;
    using Teigha.Runtime;
    using Teigha.DatabaseServices;
    using Bricscad.ApplicationServices;
    using Bricscad.EditorInput;
    using Teigha.Geometry;

    [assembly: CommandClass(typeof(ClassLibrary.Commands))]

    namespace ClassLibrary
    {
        public class Commands
        {
            [CommandMethod("doit")]
            static public void doit()
            {
                Stopwatch sw = Stopwatch.StartNew();
                Database database = HostApplicationServices.WorkingDatabase;
                using (Transaction action = database.TransactionManager.StartTransaction())
                {
                    BlockTableRecord space =
                        action.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                    for (int i = 1; i < 1001; i++)
                    {
                        Solid3d solid = new Solid3d();
                        solid.CreateBox(i, i, i);
                        solid.SetDatabaseDefaults(database);
                        action.AddNewlyCreatedDBObject(solid, true);
                        space.AppendEntity(solid);
                    }
                    action.Commit();
                }
                sw.Stop();
                Application.DocumentManager.MdiActiveDocument.
                    Editor.WriteMessage("\n{0}",sw.Elapsed.TotalMilliseconds);

            }
        }
    }

    [/code]

  • BTY my times are ... on a i5 laptop

    121 milliseconds @ 1000

    1184 milliseconds  @ 10000

  • Dear Konstantin,

    using ARX/BRX code you can expect (at least !) factor >= 2 compared to COM ...
    besides, when Lisp engine has the "COM-ByPass" enabled for (vla-addXXX), then (vla-addbox) will also be faster by >= factor 2 :-)

    That "COM-ByPass" is necessary for Linux, to have vlax(vla functions there, but it is tons of work, and already present, but for ~ 20% of all (vla-...) functions.
    In other words, that "COM-ByPass" enabled (vla-addbox) will be at 90% of pure BRX performance and min. 2 times faster ...

    Besides, if you place (vle-start-transaction) and (vle-end-transaction), you can even get (significant) more performance for such code constructions
    (Daniel already published some amazing results, >= factor 50) :-)

  • Hello Daniel and Torsten,

    thank you for your suggestions and comments !
    My test of course was meant as a means of testing different methods of solid3d creation
    and their relative speed within the lisp scripting environment(Apples !) and not via straight C# or C++.
    As a matter of fact to go straight ahead is mostly the fastest way to adopt(Oranges !).

    Daniel :
    I have used your code straight and embeded in a .NET Lispfunction,  the results are obvious :
    straight C#                                                      Lispfunction C#
    111 milliseconds @ 1000                          
    1006 milliseconds @ 1000

    1464 milliseconds  @ 10000                      9828  milliseconds  @ 10000


    Torsten :

    I am trying to understand what you mean...

    When the Lisp engine has the "COM-ByPass" enabled (necessary for Linux)  is faster..right ?

    • How can the "COM-ByPass" be enabled or desabled  ??
    • How can I use the 2 vle- ... functions you suggest ? like in the following code :

    [code]

    (defun c:1001bx ()
     
     (setq iter (fix (getreal "How many iterations :\n")))
     
     ; Set a Timer !

       (if (wcmatch (getvar "ACADVER") "*Bricscad*")
        (vle-start-transaction)
        )
     
      (setq startTimer (getvar "millisecs"))
     
      (repeat iter
       (entmake solBoxBCAD)
       )
     (prompt (strcat "\r Population Complete - Elapsed time: "
                     (rtos (- (getvar "millisecs") startTimer))
                     )
             )
     
     (if (wcmatch (getvar "ACADVER") "*Bricscad*")
        (vle-end-transaction)
        )
     
      (princ)
       
      )

    (setq solBoxBcad
          '(
        (0 . "3DSOLID")     (100 . "AcDbEntity")     (67 . 0)     (410 . "Model")     (8 . "0")     (100 . "AcDbModelerGeometry")     (70 . 1)     (1 . "700 0 1 0 ")
        (1 . "@33 Open Design Alliance ACIS Builder @12 ACIS 22.0 NT @24 Wed Jul 18 10:59:32 2012 ")
        (1 . "1 9.9999999999999995e-007 1e-010 ")
        (1 . "body $-1 -1 $-1 $1 $-1 $-1 #")   ................................etc.

    [/code]


    • How do they relate to the "COM-ByPass" if at all  ??

    Could you please be more specific on how to make the lisp engine faster for (entmake list) ?

    Thanks


    Best Regards

    Konstantin




  • Dear Konstantin,

    that "COM-ByPass" is not related to (vle-start-transaction) / ((vle-end-transaction) ...
    that COM-bypassing mechanism is already enabled in V12.2., but not yet for (vla-addBox) function.

    So once this is also implemented for (vla-addBox), then there will be an significant performance improvement.

    To get (entmake) faster, using start/end transaction, code is likely as you mentioned :
    [code]
    (setq startTimer (getvar "millisecs"))

    (if vle-start-transaction (vle-start-transaction))
    (repeat iter
       (entmake solBoxBCAD)
    )
    (if vle-end-transaction (vle-end-transaction))

    (prompt (strcat "\r Population Complete - Elapsed time: "
                     (rtos (- (getvar "millisecs") startTimer))
                  )
    )
    [/code]

    In generally, I would prefer (vla-addBox) instead of (entmake) ...
    Many greetings !
  • >>within the lisp scripting environment Ah yes, I think you will find C# 's (and BRX) relative performance to increase as the calls get chunkier, I.e. extending the arguments to include the layer, rotation etc. Fun stuff : )


  • Dear Torsten,
    thanks for the Informations !
    I tried the 2 functions (vle-start-transaction) and (vle-end-transaction) for the COM and the C# Lispfunction.
    Here are the results (in millisecs) :
                           No. of Boxes        COM (vla-addbox...)      C#.NET Lispfunction(createSolidBox...)
    ------------------------------------------------------------------------------------------------------------------------      
    Using  VLE-        @ 1000                   110                                280
                            @ 10000                 1076                               2621
    ------------------------------------------------------------------------------------------------------------------------
    NOT using         @ 1000                   1029                               1155
      VLE-               @ 10000                10389                             11622
    ------------------------------------------------------------------------------------------------------------------------

    As it can be seen, the performance boost of using vle- is significant !!
    Do all Lispers know this ?    Is it documented ?

    I have used this function

    [code]
    (defun 1001bx   (iter vle-Flag  AX-Flag / Mspace startTimer )
     
     (setq Mspace   (vla-get-modelspace
                     (vla-get-activedocument
                      (vlax-get-acad-object)))
           )
     
      ; Use vle- for light speed !
       (if vle-Flag  (vle-start-transaction))
       
      ; Set a Timer !
      (setq startTimer (getvar "millisecs"))
     
      (if AX-Flag
       (repeat iter
        (vla-addbox Mspace (vlax-3d-point (list 0.0  0.0  0.0)) (abs iter) (abs iter) (abs iter))
        )
       (repeat iter
        (CreateSolidBOX (list 0.0  0.0  0.0) (list 1.0  1.0  1.0) nil)  ;; a C# Lispfunction
        )
       )
        
      (prompt (strcat "\r Population Complete - Elapsed time: "
                     (rtos (- (getvar "millisecs") startTimer))
                     )
             )
     ; deactivate vle- light speed engine !
       (if vle-Flag (vle-end-transaction))
          
      (princ)
      )
    [/code]

    Lisp Function Calls are as follows :
                         No. of Boxes        COM (vla-addbox...)      C#.NET Lispfunction(createSolidBox...)
    ------------------------------------------------------------------------------------------------------------------------      
    Using  VLE-        @ 1000            (1001bx  1000  T  T )                  (1001bx  1000  T  nil )
                            @ 10000           (1001bx  10000  T  T )                (1001bx  10000  T nil)
    ------------------------------------------------------------------------------------------------------------------------
    NOT using         @ 1000             (1001bx  1000  nil  T )                (1001bx  1000  nil  nil )
      VLE-               @ 10000            (1001bx  10000  nil  T )              (1001bx  10000  nil  nil )
    ------------------------------------------------------------------------------------------------------------------------
    Thanks
    Best Regards



  • Dear Konstantin,

    great results :-)
    In fact, using a Transaction especially around Database operations can really boost performance - simply, because graphical updates are delayed, and reactors and other DB operations are "bundled" ... as mentioned, Daniel had tried this a while ago, with around factor 50 boost :-)

    Nevertheless, using transactions is indeed a HighEnd feature, which should be used with care ...

    Now imagine, when (vla-addBox) and similar are fully covered by "COM-ByPass", which gives at least factor 2 again ...

    Currently I'm working on a "LISP Developer Support Package", which includes a comprehensive documentation for all the new Lisp Engine features introduced with V12.2. :
    - VLE function set (+ emulation Lisp file for older Bcad + Acad + other systems; vle-extension.lsp is already installed in Bricscad folder, you might have a look at it)
    - "COM-ByPass" technology (how it works)
    - built-in automatic Lisp Optimiser
    - built-in Lisp Profiler
    - Lisp Benchmark system
    - DEScoder.exe + its help

    At this moment, it is ready for 50%, hope to get this package completed during August -> then it will be added to ApplicationsCatalogue.

    Many greetings to all !
  • Hello Torsten,
    thanks for the Information...i am looking forward to work with the "LISP Developer Support Package" !
    Regards
This discussion has been closed.