Inventor API代码性能优化 - 2
2015-09-15 17:39
197 查看
上篇我们谈到一些场景。本篇我们先来看看VBA编程可以优化的方面。大家熟悉的,VBA里有个缺省的对象ThisApplication,它是Inventor API的顶层入口。用起来比较方便,但其实会有所消耗,以下面的代码为例,它访问Locale属性10万次,花费了74.8 秒(进程外的话)。
而稍作改动,将只需要18.8秒。可以注意到其先是获取到app,然后调用10万次。原理很简单,前面的ThisApplication相当于每次都取用ThisApplication,存在读取调用,而后者只是调用一次,接下来都是引用。
让我们稍作改动如下, 时间减少到9.7秒。
背后的故事是因为使用For Each的时候,Inventor提前知道您讲遍历一个集合,就会先从内部优化。而count item的模式,Inventor不知您是遍历一次呢,还是多次呢,还是整个集合,所以提前不会做什么优化工作。
而下面这段代码,不仅效率提高,而且也美观些。
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}")
相关文章推荐
- 使用dlopen和dlsym来使用C++中的类
- php处理防止XSS攻击类
- vs,c++获取操作系统
- Java语言中使用OpenMP
- PHP Session与Cookie详解
- Java Servlet 技术简介
- Java进阶之路 异常
- Java语言中使用OpenMP
- PHP中的Session和Cookie应用
- Java multithread
- python爬虫介绍,HTML数据提取
- 关于java普通类怎样获取当前的WebRoot目录。
- Java8 Lambda表达式之比较器
- Struts-config.xml配置文件讲解
- PHP开发中常见的安全问题详解和解决方法
- PHP CURL CURLOPT参数说明
- PHP防止SQL注入和XSS攻击
- 值得推荐的C/C++框架和库
- pgpgin|pgpgout|pswpin|pswpout意义与差异
- Qt自带的软件安装包制作工具