|
No, the Editor isn't exactly slow per-se (that is determined by the complexity of the drawing, external references, etc.).
Again, there's no 'need' to do either, unless required by APIs exposed... There's something to be said for simplicity, and (more importantly?) how maintainable your code ends up being... I've learned from several mentors, that it may often be desirable to intentionally make code a bit slower, for the sake of maintainability down the road.
Performance is an inherent benefit of using .NET API over ActiveX (VBA, Visual LISP), so getting really nitty-gritty on performance side should be reserved for truly massive calculations, etc. where not already common-sensical.
Cheers
"How we think determines what we do, and what we do determines what we get."
Sincpac C3D ~ Autodesk Exchange Apps
Computer Specs:
Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000
Ok, first off, thank you SO much to whomever mentioned selection sets; I have no idea what my problem was with them before, but the speed increase for a standard drawing set (main layout, a few subassemblies, and a bunch of details) has sped up about 50x. This is mostly gained on big layouts, but whatever. Given this thing doesn't even need to be all that speedy, this is AWESOME.
I changed my application to establish an AcadDocument instead of AcDxDocument, changed the "open" to be compatible, and had to change ZERO other code. Establishing a SelectionSet is done like this (in my case):
Then, as my old script did, it checks through all entities (for each AcadEnt in SelectionSet), of which there should only be 1 (instead of millions).Code:Set SelectionSet = AcadDocument.SelectionSets.Add("SS") Dim grpCode(0) As Integer grpCode(0) = 2 filterType = grpCode Dim grpValue(0) As Variant grpValue(0) = "TEST_BLOCK" filterData = grpValue SelectionSet.Select acSelectionSetAll, , , filterType, filterData
Literally, all of the slowness of my code, now, is opening and closing the document (which I can't really change), and my computer is extremely fast.
OMG I am so happy. If any of you are ever around these parts, please hit me up for a beer or 12.
Actually, made it slightly smarter; turns out you can put "*" into that grpValue, then I just iterate through the blocks. Selection set creation is the slow part of my process, so creating a set of ALL blocks is a lot faster. Creating a selection set on my ~25MB test file (lots of entities) takes about 1/2 second to make a selection set for the block "TEST_BLOCK", then its essentially instantaneous to get all the data from it. So, since I am looking for about 35 blocks, the creation of the selection set takes (roughly) 0.25s x 35. However, creating a selection set for ALL blocks still takes about 1/2 second, but you can search through those 35 items to find the one you want almost instantaneously. So, for my large drawing (appx):
make selection set for each block then process = 1/2s x how many blocks you need
make a selection set for ALL blocks then search for the block you need inside the selection set = 1/2s x (~0 x # of blocks).
Edit: Actual numbers (just using that one large file, so this is kindof "worst/best case scenario", and excludes time to open AutoCAD {~2s}).
Old way (VBA, no SS, ObjectDBX): 95s (average over 3 attempts)
New way #1 (VBA, SS, one-selection-set-per-block): 17.8s (average over 10 attempts)
New way #2 (VBA, SS, all blocks in selection set, search selection set for block): 6.6s (average over 10 attempts)
So, my speed guesses of 50x faster were exaggerated, but with the speed of this being only 6.6s, I can probably find some more ways to speed up my code (cutting 2s off 95s wasn't worth it, now it might be). Time to clean up code .
Last edited by e_casagrande394681; 2015-01-16 at 10:31 PM.
If only you could make a single SelectionSet of just the Blocks you were after, using a concatenated string... Shucks. *kicks dirt* *chortle* *pretends to have a serious face again*
No, seriously... Unless VBA has somehow deviated from what both LISP and .NET do, you can supply a concatenated string as a filter parameter, such as "TEST_BLOCK1,TEST_BLOCK2,TEST_BLOCK3" or simply "TEST_BLOCK*" using WCMATCH. This will yield a SelectionSet of only the corresponding Blocks (be mindful of what 'space' their in if needed; see DXF code 410), which will be even faster than iterating a SelectionSet of all Blocks.
Cheers
"How we think determines what we do, and what we do determines what we get."
Sincpac C3D ~ Autodesk Exchange Apps
Computer Specs:
Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000
You are correct; I will worry about adding that later. However, I am faced with a curious new issue: if drawings are drawn correctly, this selectionset method is a LOT slower than my old way. Still looking for something to speed this up, but seems with editor, you can't get drawings to process in under about 1 second. (.3s to load, .5s for selection set, .3s for everything else)
However, since the code for the two are virtually identical, I think I might find out at ROUGHLY where the filesize becomes more advantageous of one vs. the other and process it accordingly; I think it's somewhere around 250k. Still, on my typical drawing set, this is WAYYYYYYYYYY faster, and is probably way less likely to crash (my document would iterate through BILLIONS of entities to get the ones I want, now it's ~33 entities per drawing).
Thanks for everything! I'll clean up the code for what I did and post it here once I have what I think is a clean system coded.
I'll be glad to see your code and, possibly, give some contribution to make it faster.
What BB said about concatenating is true so that you can narrow blocks selection to just the ones you need.
A bit sorry for Lord Fener this round, but still curious to compare the "dark" code speed to the VBA one in this case. So as to give it a why this thread should stay in this topic
I am currently cleaning up my code to be more VB.NET-like, and I ultimately still want to move to VB.NET for a few reasons:
a) speed: VB.NET doesn't have many of the annoying random delays of VBA; I seemingly can have the best of both worlds (ObjectDBX loading speed, Editors ability to only select what I want).
b) future-proof: I realise this is a silly concept, as it will always require recoding slightly, but it just seems like VB.NET is "better", and is definitely faster.
I am currently trying to fix all the bandaids of my old code, but the meat-and-potatoes part (reading / writing) work perfectly. The way the old system worked was pretty annoying (a lot of rownumber +1, dwgnumber +ubound(thisrandomarray), etc), and made fixing coding errors very challenging.
I'll update this when I have all that fixed, then see what I can change to make it work in VB.NET (which, now, I think I understand a lot more).
Last edited by e_casagrande394681; 2015-01-20 at 03:21 PM.
I did the same when migrating from Visual LISP (ActiveX), at first... Got a couple of VB (not VBA) apps working, got really motivated after seeing the performance gains, etc. and then ultimately found it incredibly hard to find 'real' VB code samples of how to do what I was after... I kept finding C# for next to everything instead (which at the time was frustrating).
I've since been coding in C#, and find it worlds more common-sensical than VB ever was to me - I 'thought' VB would be the most readable, jumping from ActiveX, and to some small extent I was correct in the beginning - the flaw in my logic was approaching .NET as I did Visual LISP, which led to a great deal of confusion. Only when I took a step back, and approached .NET as something entirely new (i.e., away from AutoCAD altogether) did it start to 'register' for me. Stepping into C# in lieu of VB also helped make a clean start with something new.
HTH
"How we think determines what we do, and what we do determines what we get."
Sincpac C3D ~ Autodesk Exchange Apps
Computer Specs:
Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000