VisualBasic代码优化总结

精用Boolean表达式,让代码再减肥

1、传统方法:
    If SomeVar > SomeOtherVar Then
        x = x + 1
    End If

2、更简练的方法
   x = x - (SomeVar > SomeOtherVar)

1、传统方法:
    If SomeVar > SomeOtherVar Then
      BoolVal = True
    Else
      BoolVal = False
    End If

2、更简练的方法
    BoolVal = (SomeVar > SomeOtherVar)

用InStr函数实现代码减肥
检测字符串中是否包含一个元音字母


1、传统方法:
If UCase$(Char) = "A" Or UCase$(Char) = "E" Or UCase$(Char) = "I" Or UCase$(Char) = "O" _
Or UCase$(Char) = "U" Then
'it is avowel
End If

2、更简练的方法
If InStr("AaEeIiOoUu", Char) Then
'it is avowel
End If

可能BUG:Char长度为1时正常,长度超过1时可能出现Char="Aa"的可能


检查Word中是否包含一个季节的名字

1、传统方法:
If LCase$(word) = "winter" Or LCase$(word) = "spring" Or LCase$(word) = _
"summer" Or LCase$(word) = "fall" Then
'It is a season'sname
End If

2、更加简练的方法:
If InStr(";winter;spring;summer;fall;", ";" & word & ";") Then
'It is a season'sname
End If

可能BUG:Word="winter;"时出错,不推荐使用

转换数字0到9的相应英文名称为阿拉伯数字

1、传统方法:
Select Case LCase$(word)
    Case "zero"
        result = 0
    Case "one"
        result = 1
    Case "two"
        result = 2
    Case "three"
        result = 3
    Case "four"
        result = 4
    Case "five"
        result = 5
    Case "six"
        result = 6
    Case "seven"
        result = 7
    Case "eight"
        result = 8
    Case "nine"
        result = 9
End Select

2、更加简练的方法:
result = InStr(";zero;;one;;;two;;;three;four;;five;;six;;;seven;eight;nine;", _
";" & LCase$(word) & ";") \ 6

可能BUG:同上

函数名巧做局部变量


1、传统方法:
Function Max(arr() As Long) As Long
    Dim res As Long, i As Long
    res = arr(LBound(arr))
    For i = LBound(arr) To UBound(arr)
        Ifarr (i) > resThenres = arr(i)
    Next
    Max = res
End Function

2、更加简练的方法:
Function Max(arr() As Long) As Long
    Dim i As Long
    Max = arr(LBound(arr))
    For i = LBound(arr) To UBound(arr)
        If arr(i) > Max Then Max = arr(i)
    Next
End Function

减少加载窗体、控件数目和用标签代替文本框

使用Unload方法卸载窗体时,只能释放部分窗体所占空间。要释放所有空间,可用关键字Nothing使窗体的引用无效:

    Set Form = Nothing

使用控件数组添加控件所消耗的资源比直接向窗体添加多个相同类型的控件消耗的资源要少。
标签控件Label占用的Windows资源比文本框Textbox少。例如,当窗体上需要一个隐藏的控件保存文本时,使用标签更有效。

使用磁盘文件或资源和组织模块

尽量把相关的过程放在同一模块中,让VisualBasic只在需要时才加载模块。

使用动态数组并在删除时回收内存

使用动态数组代替固定数组。当不再需要动态数组的数据时,用Erase或ReDimPreserve放弃不需要的数据,并回收数组所用内存。例如,用以下代码可回收动态数组所用空间:

    Erase MyArray

    ReDim Preserve MyArray(10, smallernum)

回收被字符串或对象变量用过的空间

要想应用程序尽量小,就得尽可能回收这些变量所用空间。将零长度字符串赋给字符串变量,可回收其空间:

    SomeStringVar = ""


使用整数(Integer)和长整数(Long)

使用Integer和Long替代Single,Double和Currency后,代码的运行速度可以提高将近10倍,因为VB处理Integer和Long的能力远远高于处理其它几种数据类型。小数也可以保存在Integer类型的变量中。例如程序中约定有三位小数,那么只需要将保存在Integer变量中的数值除以1000就可以得到结果。

使避免使用变体

1、错误代码:

    Dim FSO
    Set FSO = New Scripting.FileSystemObject

    或

    Dim FSO As Object
    Set FSO = New Scripting.FileSystemObject

2、正确代码:

    Dim FSO As New FileSystemObject

尽量避免使用属性

存取变量的速度是存取属性的速度的20倍左右。

1、常规代码:

    Dim intCon As Integer
    For intCon = 0 To UBound(SomVar())
        Text1.Text = Text1.Text & vbCrLf & SomeVar(intCon)
    Next intCon

2、高效代码:

    Dim intCon As Integer
    Dim sOutput As String
    For intCon = 0 To UBound(SomeVar())
        sOutput = sOutput & vbCrLf & SomeVar(intCon)
    Next
    Text1.Text = sOutput

尽量使用数组,避免使用集合

    由于集合(Collection)是一个对象,数组的存取速度可以达到集合的100倍。

展开小的循环体

    如果循环体只会循环2到3次,而且循环体由几行代码组成,可以把循环展开,循环会占用额外的CPU时间

避免使用很短的函数

    调用几行代码的函数所花费的时间或许比此执行函数中的代码需要更长的时间。

减少对子对象的引用

1、常规代码:
    frmMain.Text1.Text = "LearnVB"
    frmMain.Text1.Alignment = 0
    frmMain.Text1.Tag = "Itsmylife"
    frmMain.Text1.BackColor = vbBlack
    frmMain.Text1.ForeColor = vbWhite

2、高效代码:

    注释:使用With
    With frmMain.Text1
        .Text = "LearnVB"
        .Alignment = 0
        .Tag = "Itsmylife"
        .BackColor = vbBlack
        .ForeColor = vbWhite
    End With

    注释:使用另一个对象保存子对象
    Dim txtTextBox As TextBox
    Set txtTextBox = frmMain.Text1
    txtTextBox.Text = "LearnVB"
    txtTextBox.Alignment = 0
    txtTextBox.Tag = "Itsmylife"
    txtTextBox.BackColor = vbBlack
    txtTextBox.ForeColor = vbWhite

3、低效代码

    注意,上面提到的方法只适用于需要对一个对象的子对象进行操作的时候,下面这段代码是不正确的,原因是With块编译后会形成一个分枝,会增加了额外的处理工作。

    With Text1
        .Text = "LearnVB"
        .Alignment = 0
        .Tag = "Itsmylife"
        .BackColor = vbBlack
        .ForeColor = vbWhite
    End With

检查字符串是否为空

    进行字符串比较需要的处理量甚至比读取属性还要大。

1、常规代码:

    If Text1.Text = "" Then
注释:执行操作
    End If

2、高效代码:

    If Len(Text1.Text) = 0 Then
    注释:执行操作
    End If

去除Next关键字后的变量名

1、错误的代码

For iCount = 1 to 10
注释:执行操作
Next iCount

2、正确的代码

For iCount = 1 to 10
注释:执行操作
Next  

使用数组,而不是多个变量

    当你有多个保存类似数据的变量时,可以考虑将他们用一个数组代替。在VB中,数组是最高效的数据结构之一。

变长和定长字符串

    从技术上来说,与变长字符串相比,定长字符串需要较少的处理时间和空间。但是定长字符串的缺点在于在很多情况下,你都需要调用Trim函数以去除字符串末的空字符,这样反而会降低代码效率。所以除非是字符串的长度不会变化,否则还是使用变长字符串。

编译优化   

    我所见过的很多VB程序员从来没有使用过编译选项,也没有试图搞清楚各个选项之间的差别。下面让我们来看一下各个选项的具体含义。

  1.P-代码(伪代码)和本机代码

   你可以选择将软件编译为P-代码或是本机代码。缺省选项是本机代码。那什么是P-代码和本机代码呢?

      P-代码:当在VB中执行代码时,VB首先是将代码编译为P-代码,然后再解释执行编译好的P-代码。在编译环境下,使用这种代码要比本机代码快。选择P-代码后,编译时VB将伪代码放入一个EXE文件中。

   本机代码:本机代码是VB6以后才推出的选项。当编译为EXE文件后,本机代码的执行速度比P-代码快。选择本机代码后,编译时VB使用机器指令生成EXE文件。

在使用本机代码进行编译时,我发现有时候会引入一些莫名其妙的错误。在编译环境中我的代码完全正确地被执行了,但是用本机代码选项生成的EXE文件却 不能正确执行。通常这种情况是在卸载窗口或弹出打印窗口时发生的。我通过在代码中加入DoEvent语句解决了这个问题。当然出现这种情况的几率非常少, 也许有些VB程序员从来没有遇到过,但是它的确存在。  

   在本机代码中还有几个选项:

   a)代码速度优化:该选项可以编译出速度较快的执行文件,但执行文件比较大。推荐使用

   b)代码大小优化:该选项可以编译出比较小的执行文件,但是以牺牲速度为代价的,不推荐使用。

   c)无优化:该选项只是将P-代码转化为本机代码,没有做任何优化。在调试代码时可以使用。

d)针对PentiumPro优化:虽然该项不是本机代码中的缺省选项,但是我通常会使用该选项。该选项编译出的可执行程序在PentiumPro和 Pentium2以上的机器上可以运行得更快,而在比较老的机器上要稍稍慢一些。考虑到现在用Pentium2都是落伍,所以推荐大家使用该选项。

   e)产生符号化调试信息:该项在编译过程中生成一些调试信息,使用户可以利用VisualC 一类的工具来调试编译好的代码。使用该选项会生成一个.pdf文件,该文件记录了可执行文件中的标志信息。当程序拥有API函数或DLL调用时,该选项还是比较有帮助的。

  2.高级优化

高级优化中的设置可以帮助你提高软件的速度,但是有时候也会引入一些错误,因此我建议大家尽量小心地使用它们。如果在代码中有比较大的循环体或者复杂 的数学运算时,选中高级优化中的某些项会大幅度提升代码的性能。如果你使用了高级优化功能,我建议你严格测试编译好的文件。

   a)假定无别名:可以提高循环体中代码的执行效率,但是在如果通过变量的引用改变变量值的情况下,例如调用一个方法,变量的引用作为方法的参数,在方法中改变了变量的值的话,就会引发错误。有可能只是返回的结果错误,也有可能是导致程序中断运行的严重错误。

b)取消数组绑定检查、取消整数溢出检查和取消浮点错误检查:在程序运行时,如果通过这些检查发现了错误,错误处理代码会处理这些错误。但是如果取消 了这些检查,发生了错误程序就无法处理。只有当你确定你的代码中不会出现上面的这些错误时,你才可以使用这些选项。它们将使软件的性能得到很大的提升。

   c)允许不舍入的浮点操作:选择该选项可以是编译出来的程序更快地处理浮点操作。它唯一的缺点就是在比较两个浮点数时可能会导致不正确的结果。

   d)取消PentiumFDIV安全检查:该选项是针对一些老的Pentium芯片设置的,现在看来已经过时了。

尽量使用事务处理更新数据库

    VB的事务处理包括以BeginTrans开始,以CommitTrans或Rollback结尾的多条数据 库操作指令。事务处理除了能很好的保证数据库的完整性以外,同时能大大提高数据库批量更新的效率。这是因为如果数据库更新操作没有使用事务处理,则每次 Update操作都会引起数据库写盘一次。使用事务处理后,更新只在内存缓冲区内进行,执行CommitTrans时才将所有修改一次写回到磁盘中。使用 事务处理要注意一下几点:

  (1)事务处理要有很完善的错误检查机制;

  (2)因为VB在事务处理结束前对数据库使用了页面锁.所以在多用户环境中,如果事务被挂起,则其他用户将无法访问上锁的数据。

尽量使用代码分解Select检索操作

    使用Select进行数据库操作固然简单易用,但如果将一些检索操作分解为等价的手工检索代码,则对数据库的检索速 度将大大加快.分解的基本方法是对检索关键字段进行索引,利用Seek方法定位后,根据索引的数据库已经排序的特点,进行遍历查找.对于遍历范围不是很宽 时,这种方法能几十倍的提高数据库的访问速度.