关于VB编译的问题。。。

harp 2002-01-28 10:56:50
把VB编译成EXE过程中,本机编译,无论是速度优化还是大小优化均在编译过程中死机,(也不是死机,就是程序无响应),但选用本机编译的无优化则可以,或是选择P代码编译亦可,为何?
再者,P代码编译与本机编译有何不同?
...全文
82 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
dbcontrols 2002-01-28
  • 打赏
  • 举报
回复
编译型和解释型应用程序的比较


按照缺省规定,Visual Basic 将应用程序编译成可运行的解释型或 P-code 程序。运行时,动态链接库 (DLL) 将翻译或解释执行程序中的指令。Visual Basic 专业版和企业版还可将程序编译成 .exe 本机代码。在许多情况中,运行本机代码比运行解释型代码本质上要快得多。但事情并非总是这样。以下是一些有关本机代码编译的一般指南:

若代码做了大量固定类型的、非字符串变量的基本操作,则其产生的本机代码将与编译的 P-code 操作码产生最大的反差。然而,对于复杂的经济计算或生成分形图形,用本机代码有很多好处。


计算密集型程序,或在局部数据结构中处理大量的位和字节操作的程序,用本机代码就可获得明显的好处。


在许多程序中,特别是那些含有大量 Windows API 调用,COM 方法调用和字符串操作的程序,本机代码不比 P-code 快多少。


如果应用程序主要含有来自 Visual Basic for Applications 运行库的函数,那么就看不到多少本机代码的好处,这是因为 Visual Basic for Applications 运行库已经高度优化了。


含有大量子例程调用而非内嵌过程的代码,用本机代码也似乎不太快。这是因为设置栈结构,初始化变量,返回时的清除等工作,用 P-code 引擎和用本机代码所花费的时间相同。
注意,调用一次对象、DLL 或 Visual Basic for Applications 运行函数,都会消弱本机代码性能上的优点。这是因为执行代码所花时间相对地少,而大量时间(常常达到 90-95%)花在窗体、数据对象、Windows DLL,或 Visual Basic for Applications 运行库,以及处理内部字符串和变量上。

实际测试中,典型情况是客户应用程序总的执行时间有 5% 用于执行 P-code。因此,如果本机代码是瞬时执行的,则在这些程序中用本机代码也只能改进性能最高达 5%。

本机代码的目的是可让程序员用 Basic 编写一小片代码或有大量计算的算法。这些,由于性能问题,在以前是决不可能的。使用这些运行非常快的“小片”,也能改善应用程序特定部分的响应,从而改进了整个应用程序的感觉性能。

详细信息 关于本机代码的编译的详细信息,请参阅“再论编程”的“将工程编译成本地代码”。
dbcontrols 2002-01-28
  • 打赏
  • 举报
回复
用“本机代码”选项来编译工程意味着您写的代码将完整地编译为处理器芯片的本地指令,而不是编译为p-code。这将大大加速循环和数学计算,并可以加速对 MSVBVM60.DLL提供的服务程序的调用。然而,这并不能减少对 DLL 的需要。
dbcontrols 2002-01-28
  • 打赏
  • 举报
回复
优化代码


除非应用程序是用来产生分形图形的,否则应用程序看上去并不受限于代码的实际处理速度。其它典型的因素,如显示速度、网络延迟或磁盘操作,才是应用程序速度的限制因素。比如,导致窗体加载慢的原因,是窗体上控件和图形的个数太多,而不是由于 Form_Load 事件中的代码太慢。尽管如此,代码本身的速度也可以成为限制应用程序速度的瓶颈,特别是经常调用到的例程。这种情况下,可采用以下的几种技术来优化应用程序的真实速度。

避免使用 Variant 变量。


使用 Long integer 变量和整数运算。


将常用的属性缓存在变量中。


使用内嵌过程替代过程调用。


尽可能使用常数。


用 ByVal 传递参数,而不用 ByRef。


使用类型确定的可选参数。


利用集合的优点。
即使您并不想优化代码的速度,这也有助于了解这些技术及其基本原则。而且,一旦养成选择高效率算法作为代码的习惯,就可以从总体上大大改善应用程序的速度。

避免使用 Variant 变量
Variant 变量是 Visual Basic 中的缺省变量。这对于初学者以及处理速度不成问题的应用程序来说,是非常方便的。然而,如果想优化应用程序的实际速度,就要避免使用 Variant 变量。因为,运行时 Variant 将转化为其它适当的数据类型,那么直接采用其它简单的数据类型,就会避免不必要的操作而加快应用程序的速度。

避免使用 Variant 变量的一种好办法是使用 Option Explicit 语句,此时所有的变量都必须声明。要使用“Option Explicit”,就要在“工具”菜单中启动“选项”对话框,选择“编辑器”选项卡,选定“要求变量声明”复选框。

在声明多个变量时要小心:如果没有用 As type 子句,它们实际上被声明为 Variant 变量。在下面的例子中,X 和 Y 是 Variant 变量:

Dim X, Y, Z As Long

重写上面的语句,则三个变量为 Long 变量:

Dim X As Long, Y As Long, Z As Long

详细信息 关于 Visual Basic 数据类型的详细信息,请参阅“编程基础”中的“数据类型”。

使用 Long 整型变量和整数运算
算术运算中要避免使用 Currency、Single 和 Double 变量;并尽量使用 Long 整型变量,尤其在循环体中。因为 Long 整数是 32 位 CPU 的本机数据类型,所以其操作非常快;如果无法使用 Long 变量,就要尽量使用 Integer 或 Byte 数据类型。很多时候,即使在要求使用浮点数的情况下,也可以使用 Long 整数。例如,在窗体和图形控件的 ScaleMode 属性设置为缇或象素时,就可以在控件和图形方法中使用 Long 整型变量表示大小和位置。

进行除法运算时,如果不需要小数部分,就可以使用整数除法运算符 (/)。由于浮点运算需要转移到协处理器上进行,而整数运算并不需要,所以整数运算总是比浮点运算快。如果确实需要做小数运算,则 Double 数据类型比 Currency 数据类型快。

下表把各种数值数据类型按运算速度顺序列出。

数值数据类型 速度
Long 最快
Integer .

Byte .

Single .

Double .

Currency 最慢


将常用的属性缓存在变量中
变量的访问和设置速度比属性快。如果经常用到某一属性的值(如在循环体中),可以在循环体外把该属性值赋给某一变量,以后用该变量替代该属性,这样就能够提高代码的速度。一般来说,变量的处理速度比同类型的属性处理速度快 10 到 20 倍。

除非知道属性已经改变,否则在过程中就无需再次读取该属性值。可以把属性值赋予某一变量,然后在以后的代码中使用该变量。例如,象这样的代码就非常慢:

For i = 0 To 10
picIcon(i).Left = picPallete.Left
Next I

下面改写的代码就要快得多:

picLeft = picPallete.Left
For i = 0 To 10
picIcon(i).Left = picLeft
Next I

同样地,像这样的代码 . . .

Do Until EOF(F)
Line Input #F, nextLine
Text1.Text = Text1.Text + nextLine
Loop

. . . 比下面的代码慢得多:

Do Until EOF(F)
Line Input #F, nextLine
bufferVar = bufferVar + nextLine
Loop
Text1.Text = bufferVar

然而,下面的代码完成了相同的功能,而且还要快:

Text1.Text = Input(F, LOF(F))
如上述,几种方法都实现了同样的任务;同时,最好的算法也是最优的。

同样的技术可用于处理函数的返回值。缓存函数的返回值,避免经常调用运行时的动态链接库 (DLL),Msvbvm60.dll。

使用内嵌过程替代过程调用
采用过程调用使代码更具有模块化的风格,但模块调用总是增加额外的操作和处理时间。如果循环体中多次调用某一过程,就可以直接把该过程写到循环体中去,以消除过程调用时的额外负担。但另一方面,直接把某一过程写到好几个循环体中时,重复的代码无疑要增加应用程序的大小;同时,在更改程序时,有可能忘记更改这些重复的代码,这就增加了出错的机会。

尽可能使用常数
使用常数可以加快应用程序的运行,增强代码的可读性,而且易于维护。如果代码中的字符串或数字是不变的,则可把它们声明为常数。常数在编译时只处理一次,将适当的值写进代码;而变量在每次运行应用程序时都要读取当前值。

尽量使用对象浏览器中列举的内部常数,而不要自己去创建。不要担心应用程序中引用的模块包含多余的常数;多余的常数在形成 .exe 文件时被删除。

用 ByVal 传递参数,而不用 ByRef
编写含参数的 Sub 或 Function 过程时,按值 (ByVal) 传递参数比按地址 (ByRef) 快。尽管 Visual Basic 中参数传递的缺省方式是按地址的 (ByRef) ,但实际上需要改变参数值的过程极少。如果过程中不需改变参数的值,就可以按值 (ByVal) 来传递,举例说明如下:

Private Sub DoSomething(ByVal strName As String, _
ByVal intAge As Integer)

使用类型确定的可选参数
使用 Visual Basic 5.0 中类型确定的可选参数,可以提高 Sub 或 Function 的调用速度。Visual Basic 以前版本中的可选参数只能是 Variant 的。如果过程是按值传递参数的,正如下面的例子,16 个字节的 Variant 变量保存在堆栈中。

Private Sub DoSomething(ByVal strName As String, _
Optional ByVal vntAge As Variant, _
Optional ByVal vntWeight As Variant)

使用类型确定的可选参数,每次调用时占用的堆栈空间较少,而且传递到内存中的数据也较少:

Private Sub DoSomething(ByVal strName As String, _
Optional ByVal intAge As Integer, _
Optional ByVal intWeight As Integer)

类型确定的可选参数的访问速度比 Variant 快,而且一旦数据类型错误,编译时就显示错误信息。

利用集合的优点
可以定义和使用对象的集合是 Visual Basic 的强大功能之一。尽管集合是非常有用的,但还要正确使用才能获得最好的效果:

使用 For Each...Next 替代 For...Next。


添加集合的对象时避免使用 Before 和 After 参数。


使用键集而不用几组相同对象的数组。
集合可以用 For...Next 循环进行迭代。但采用 For Each...Next 可读性更好,而且多数情况下更快。For Each...Next 是由集合的生成器实现迭代的,所以实际的操作速度将随集合对象的不同而改变。由于 For Each...Next 的最简单的实现机理就是 For...Next 的线性迭代,因此 For Each...Next 不会比 For...Next 慢。但是,有些情况下采用了比线性迭代更复杂的实现机理,所以 For Each...Next 要快得多。

如果没有使用 Before 和 After 参数,则往集合中添加对象是非常快的。否则,Visual Basic 必须在集合中检测到其它对象后,才能添加新对象。

如果对象的类型都一样,集合或数组都可以用来管理这些对象(如果对象的类型不一样,则只能用集合)。从速度的观点看,选择何种方式取决于对象的访问方式。如果能够为每一对象分配唯一的键,则集合是访问对象的最快方式。使用键从集合中检索对象比从数组中顺序遍历对象快。当然,如果没有键而要遍历对象时,则选择数组比较好。就顺序遍历方式而言,数组比集合快。

如果对象的个数少,则数组使用的内存小,并且搜索的速度快。当对象的个数在 100 左右时,集合比数组的效率高;当然,具体的数目还有赖于微处理器的速度和可用的内存。

详细信息 请参阅“再论编程”中的“用集合替代数组”。
lihanbing 2002-01-28
  • 打赏
  • 举报
回复
P代码是一种伪代码,执行的时候是解释执行,因此执行效率要低一些

742

社区成员

发帖
与我相关
我的任务
社区描述
VB 版八卦、闲侃,联络感情地盘,禁广告帖、作业帖
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧