Author Topic: Speedy code  (Read 6651 times)

0 Members and 1 Guest are viewing this topic.

cadpro

  • Guest
Speedy code
« on: June 16, 2009, 03:55:16 AM »
Hi,

How do I make this code faster?

Code: [Select]
dbxDoc = CType(AcadApp.GetInterfaceObject("ObjectDBX.AxDbDocument.17"), AxDbDocument)

        dbxDoc.Open(dwgFile)

         Dim ms As AcadEntity
 
        For Each ms In dbxDoc.ModelSpace
            If TypeOf ms Is AcadExternalReference Then
                Dim intIndex As Integer = Array.IndexOf(Src, ms.Name.ToString.ToLower)
                If intIndex >= 0 Then
                    tbl.Rows.Add(ms.Name, dwgFile, ms.Path)
                ElseIf String.IsNullOrEmpty(txtXrefs.Text) Then
                    tbl.Rows.Add(ms.Name, dwgFile, ms.Path, "")
                End If
            End If
         Next

        For Each ms In dbxDoc.PaperSpace
            If TypeOf ms Is AcadExternalReference Then
                 Dim intIndex As Integer = Array.IndexOf(Src, ms.Name.ToString.ToLower)
                If intIndex >= 0 Then
                    tbl.Rows.Add(ms.Name, dwgFile, ms.Path)
                ElseIf String.IsNullOrEmpty(txtXrefs.Text) Then
                    tbl.Rows.Add(ms.Name, dwgFile, ms.Path, "")
                End If
            End If
        Next

This is to get all parent xrefs only from a drawing.

Thanks

pkohut

  • Guest
Re: Speedy code
« Reply #1 on: June 16, 2009, 04:00:57 AM »
How slow is it?  I guess where do you think the bottle neck might be?
I don't know is the slowness from the drawing open?

Paul

ReneRam

  • Guest
Re: Speedy code
« Reply #2 on: June 16, 2009, 06:30:26 AM »
just a hint from:

http://www.dotnet2themax.com/ShowContent.aspx?ID=b7ab9163-1a7c-43c5-bb9a-0540f3e6be1c

that I got a few years ago. I thought I had also the ebook, but in any case...

"Iterating a collection with <For each... Next> is slower than <For counter = ... To ... Next>", I think I remember that it was because the For Each creates a copy of the object in the collection at each step or something like that; I'm sure the gurus here can explain the reason, but in any case I have made some tests and with large collections of complex objects I found out it's verified. So in your case I would create a SelectionSet of the ExternalReferences and then run the iteration with a "For ... to collection counted items... Next".



Draftek

  • Guest
Re: Speedy code
« Reply #3 on: June 16, 2009, 08:08:43 AM »
Offhand I'd say create a selection set with a filter to eliminate iterating every entity in the database.

cadpro

  • Guest
Re: Speedy code
« Reply #4 on: June 16, 2009, 08:37:58 AM »
Previously my code was as follows:

Code: [Select]
        Dim blk As AcadBlock
        Dim blks As AcadBlocks
        blks = dbxDoc.Blocks

        Dim Src() As String
        Src = txtXrefs.Text.ToLower.Split(",".ToCharArray)
        Array.Sort(Src)

        For Each blk In blks
           If blk.IsXRef Then
           Dim intIndex As Integer = Array.IndexOf(Src, blk.Name.ToString.ToLower)
                    If intIndex >= 0 Then
                        tbl.Rows.Add(blk.Name, dwgFile, blk.Path)
                    ElseIf String.IsNullOrEmpty(txtXrefs.Text) Then
                       tbl.Rows.Add(blk.Name, dwgFile, blk.Path, "")
                    End If
                End If
                'End If
            End If
        Next

This was extremely fast, but the problem was that it displays even nested xrefs, which I don't want to.

Quote
Offhand I'd say create a selection set with a filter to eliminate iterating every entity in the database.

Draftek:
How do I go about it?

Thanks

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Speedy code
« Reply #5 on: June 16, 2009, 11:09:14 AM »
Use ' GetHostDwgXrefGraph '.  You can tell which xrefs are nested, and which are not.  If you want to select them, then you can get that information from the block table record of the xrefs.  No need to step through the whole drawing to get this information.  If you just want to get the xref information to store it, then you don't have to go any further than what each node has, as the information is all there.

A few examples ( one might seem familiar ).
[ http://www.theswamp.org/index.php?topic=22884.0 ]
[ http://www.theswamp.org/index.php?topic=12272.msg152426#msg152426 ]
Tim

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

Please think about donating if this post helped you.

ReneRam

  • Guest
Re: Speedy code
« Reply #6 on: June 16, 2009, 11:40:17 AM »
Take a look also to this:

http://www.theswamp.org/index.php?topic=24524.msg295771#msg295771

and a little testing sub:

Code: [Select]
    Sub XrefTester()
        Dim myDWG As ApplicationServices.Document = ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim myDB As DatabaseServices.Database = myDWG.Database
        Dim xrefGraph As XrefGraph = myDB.GetHostDwgXrefGraph(True)

        Using tr As Transaction = myDB.TransactionManager.StartTransaction()
            For i As Integer = 0 To xrefGraph.NumNodes - 1
                Dim xrefName As String = Nothing
                Dim xrefGraphNode As XrefGraphNode = xrefGraph.GetXrefNode(i)
                ' Do whatever you need
                Debug.Print(xrefGraphNode.Name)
            Next
        End Using
    End Sub

Glenn R

  • Guest
Re: Speedy code
« Reply #7 on: June 16, 2009, 04:54:23 PM »
How do I make this code faster?

Still not learning eh? Ditch COM, especially externally called. That will speed it up by a factor of ~10.

Glenn R

  • Guest
Re: Speedy code
« Reply #8 on: June 16, 2009, 04:55:23 PM »
BTW, Tim had the right of it.

cadpro

  • Guest
Re: Speedy code
« Reply #9 on: June 17, 2009, 01:37:58 AM »
FYI I'm working with ObjectDBX. So will Tim's code work?

Thanks

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: Speedy code
« Reply #10 on: June 17, 2009, 01:58:42 AM »
[challenge] for cadpro :

you tell us.


sorry, the debil made me say that !  :evil:
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cadpro

  • Guest
Re: Speedy code
« Reply #11 on: June 17, 2009, 06:36:35 AM »
I had earlier reference AutoCAD Type Library and ObjectDBX Library. But since I understand from the post here that my requirements will not work with these references, I changed the reference to acdbmgd and acmgd. Then I tried to access the xref blocks using the 'GetHostDwgXrefGraph', as Tim and ReneRam suggested. But when I call this method, I get an error that says 'The specified module could not be found.' How can I accomplish what I required, by staying outside AutoCAD?

Draftek

  • Guest
Re: Speedy code
« Reply #12 on: June 17, 2009, 07:59:44 AM »
Dood!

You need to step back and figure out how your hooking into AutoCAD.

Do you know what the difference between the com type libraries and the managed .net libraries is?

A basic understanding of this is going to simplify your coding life. Okay - at least it will be a start.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8712
  • AKA Daniel
Re: Speedy code
« Reply #13 on: June 18, 2009, 12:00:04 AM »
Unfortunately, if your partying in the .DWG from outside Acad, you're not going to get good performance unless
you are working through RealDWG or are using the ODA libraries.

Are stepping though multiple .DWG files? if so, you might try using Parallel Extensions

cadpro

  • Guest
Re: Speedy code
« Reply #14 on: June 18, 2009, 09:11:50 AM »
Unfortunately, if your partying in the .DWG from outside Acad, you're not going to get good performance unless
you are working through RealDWG or are using the ODA libraries.

You are right. I realized it just now.

Quote
Are stepping though multiple .DWG files? if so, you might try using Parallel Extensions

Could you explain on Parallel Extensions?

I had started off with WPF and the design and coding is complete. Can I change this to dll? This is the code I tried to do.

Code: [Select]
Public Class Class1
    <CommandMethod("Test")> _
    Public Sub showWin()
        Dim winStart As Window1 = New Window1()

        acadapp.ShowModalDialog(winStart)
    End Sub
End Class

But I cannot call WPF form with acadapp. Is this possible in any way?

Thanks