您的位置:首页 > 编程语言

Inventor API代码性能优化 - 2

2015-09-15 17:39 197 查看
上篇我们谈到一些场景。本篇我们先来看看VBA编程可以优化的方面。大家熟悉的,VBA里有个缺省的对象ThisApplication,它是Inventor API的顶层入口。用起来比较方便,但其实会有所消耗,以下面的代码为例,它访问Locale属性10万次,花费了74.8 秒(进程外的话)。

Public Sub CallCost() 
    Dim timer As New clsTimer 
    timer.Start 

    Dim i As Long 
    For i = 1 To 100000 
        Dim code As Long 
        code = ThisApplication.Locale 
    Next 

    Debug.Print "Total time: " & Format(timer.GetTime, "0.00000") 
End Sub


而稍作改动,将只需要18.8秒。可以注意到其先是获取到app,然后调用10万次。原理很简单,前面的ThisApplication相当于每次都取用ThisApplication,存在读取调用,而后者只是调用一次,接下来都是引用。
Public Sub CallCost() 
    Dim timer As New clsTimer 
    timer.Start 

    <span style="background-color: rgb(255, 255, 102);">Dim app As Inventor.Application</span> 
    <span style="background-color: rgb(255, 255, 51);">Set app = ThisApplication</span> 

    Dim i As Long 
    For i = 1 To 100000 
        Dim code As Long 
        code = <span style="background-color: rgb(255, 255, 51);">app.Locale</span> 
    Next 

    Debug.Print "Total time: " & Format(timer.GetTime, "0.00000") 
End Sub


引用而非内联函数调用

再来一个优化,和前面类似,就是当您需要频繁调用某个对象时,尽量引用。这里有段代码遍历装配体的所有部件,获取其名字和对应的文件名。一个有500个部件的装配,循环调用10次,大约花了22.5秒。

Public Sub GetOccurrences1() 
    Dim asmDoc As AssemblyDocument 
    Set asmDoc = ThisApplication.ActiveDocument 

    Dim i As Integer 
    For i = 1 To asmDoc.ComponentDefinition.Occurrences.Count 
        Dim Name As String 
        Name = asmDoc.ComponentDefinition.Occurrences.Item(i).Name 

        Dim filename As String 
        filename = asmDoc.ComponentDefinition.Occurrences.Item(i). _ 
                   ReferencedDocumentDescriptor. _ 
                   ReferencedFileDescriptor.FullFileName 
    Next 
End Sub


让我们稍作改动如下, 时间减少到9.7秒。

Public Sub GetOccurrences2() 
    Dim asmDoc As AssemblyDocument 
    Set asmDoc = ThisApplication.ActiveDocument 

    <span style="background-color: rgb(255, 255, 51);">Dim occs As ComponentOccurrences </span>
    <span style="background-color: rgb(255, 255, 51);">Set occs = asmDoc.ComponentDefinition.Occurrences</span> 

    Dim i As Integer 
    For i = 1 To occs.Count 
        Dim Occ As ComponentOccurrence 
        Set Occ = occs.Item(i) 

        Dim Name As String 
        Name = Occ.Name 

        Dim filename As String 
        <span style="background-color: rgb(255, 255, 51);">filename = Occ.ReferencedDocumentDescriptor. _ 
                        ReferencedFileDescriptor.FullFileName</span> 
    Next 
End Sub


使用For Each而不要Count 和Item

还是以便利装配中的部件为例,以下代码将花费9.4秒。虽然比前面并未有明显改变,但不同的集合会有不同的时间优化。而且,也比count item好阅读些,对吧。

背后的故事是因为使用For Each的时候,Inventor提前知道您讲遍历一个集合,就会先从内部优化。而count item的模式,Inventor不知您是遍历一次呢,还是多次呢,还是整个集合,所以提前不会做什么优化工作。

Public Sub GetOccurrences3() 
    Dim asmDoc As AssemblyDocument 
    Set asmDoc = ThisApplication.ActiveDocument 

    Dim occs As ComponentOccurrences 
    Set occs = asmDoc.ComponentDefinition.Occurrences 

    Dim Occ As ComponentOccurrence 
   <span style="background-color: rgb(255, 255, 51);"> For Each Occ In occs </span>
        Dim Name As String 
        Name = Occ.Name 

        Dim filename As String 
        filename = Occ.ReferencedDocumentDescriptor. _ 
                   ReferencedFileDescriptor.FullFileName 
    Next 
End Sub


通过名字过去某条目Item

和集合关联的另外一种优化就是,假设要获取集合内某个对象条目,尽量用名字获取,而不要遍历一个个查找。例如,这段代码想获得某个TranslatorAddIn.

Dim dxfAddIn As TranslatorAddIn 
For i = 1 To addIns.Count 
    If addIns(i).AddInType = kTranslationApplicationAddIn Then 
        Dim desc As String 
        desc = addIns(i).Description   
        If desc = "Autodesk Internal DXF Translator" Then 
            Set dxfAddIn = addIns.Item(i) 
            Exit For 
        End If 
    End If 
Next


而下面这段代码,不仅效率提高,而且也美观些。

Dim dxfAddIn As TranslatorAddIn 
Set dxfAddIn = addIns. _ 
                 ItemById("{C24E3AC4-122E-11D5-8E91-0010B541CD80}")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: