如何减少VB6项目的启动时间/精确定位需要这么长时间

时间:2011-11-17 22:30:28

标签: performance vb6

我使用了两个vb6应用程序。其中一个启动非常快,而另一个需要很长时间。我想我会做一些分析,找出为什么需要这么长时间。

所以我在开始时按F8开始,我意识到启动时间的很大一部分实际上是在我点击F8的时间和突出显示第一行代码的时间之间。

以下哪项最有可能造成这种情况?

  • 依赖项数
  • 在群组项目中有太多项目,而不是将它们称为dll
  • 表格数量
  • 启动表单中的对象数
  • 所有表格上的对象数量
  • 还有什么?

作为奖励,我会喜欢任何关于如何更具体地确定问题的想法,如果它可能在多个领域。

谢谢!

编辑:似乎我对减速发生的“确切位置”可能还不够清楚。所以要明确我创建了以下过程:

Sub Main()
End Sub

就是这样,它在一个模块中除了这两行之外绝对没有任何内容。没有表单被加载,虽然还有其他模块“Dim o as New SomeObject”,但我知道这些对象没有被实例化,因为我知道visual basic不会创建以这种方式声明的对象,直到你实际使用它们为止第一次。

我相信我现在已经在技术上尽可能地优化了启动代码。但它仍然需要相同的启动时间。

编辑2:我刚刚意识到编译后的应用程序实际上启动速度相当快。它只是在需要很长时间的ide中启动它。但是,我对我的速度比对客户的关心更多,因为他们只是启动一次并让它一整天都在运行,而我每天都会开始运行几十次。

5 个答案:

答案 0 :(得分:5)

由于您提到您正在使用Sub Main,因此在加载任何表单之前发生延迟,最可能的问题是问题出在您链接的DLL的初始化例程中。

每个DLL都会导出一个入口点函数(通常为DllMain),该函数在链接到DLL后立即调用。在VB6中,这将在Sub Main执行之前。

由于这个原因,DLL作者在DllMain中做任何重要的事情通常都是非常糟糕的形式,但是许多懒惰的DLL开发人员在他们的DllMain中做了各种各样的工作,直到后来才真正完成。如果你能找出罪魁祸首并重写它,那将解决你的问题。如果你不能重写它,你至少可以找到一种方法来动态加载DLL而不是链接它。

还有一件事可以加快依赖于大量DLL的任何Windows应用程序的启动时间,即rebase all the DLLs

编译EXE和DLL以假定它们将在称为Preferred Load Address的某些起始地址的内存中加载。例如,DLL可能包含指定要跳转到的绝对地址的JMP指令(基本上是GOTO)。 DLL文件本身在开头会包含一条指示Windows的小指令,“嘿,我希望我将从内存地址X开始加载,因为我的代码包含一堆JMP到假设的位置相对于地址X.“因此,现在Windows将尝试将该DLL放在X位置。但是如果其他东西已经在使用该空间,它别无选择,只能把它放在其他地方,称之为Y.当发生这种情况时,Windows必须通过整个可执行映像的DLL并用“X + n + YX”代替“X + n”形式的所有地址...这称为变基,它很慢。

如果您事先知道DLL将在您自己的应用程序中加载另一个DLL,则可以通过预先重新绑定所有DLL以使它们不连续来显着增加启动时间。

答案 1 :(得分:3)

该时间可能花在初始化启动表单上的所有对象上。在启动表单上有很多COM对象或UserControls吗?反过来,他们可能会加载他们正在使用的其他对象。

调试此方法的最佳方法是从启动表单中一次删除一个对象(不要担心内置控件,只需担心外部对象),直到找出哪一个占用时间最多启动。然后,您可以尝试通过优化该对象中的启动代码来加快启动时间,或者至少通过推迟创建该对象直到实际需要它为止。

答案 2 :(得分:3)

该项目有多大?它可能正在对p代码进行中间编译,因此它可以运行它。 您可以使用“选项”对话框中的“编译”设置进行调整。

答案 3 :(得分:0)

从这里无从告知每种情况都是独特的。

可以是任何或所有。上次我不得不与其他人处理VB代码,FormLoad在.bas文件中运行了一个函数,该文件设置了大约20个记录集......

除了在调试中测量性能的非常粗略的措施之外,对于VB6来说,它更像是在解释它。

你可以获得一个分析工具,谷歌VB6分析工具。

或者你可以添加一个noddy记录器。打开文件的代码位会为其添加带时间戳的条目。然后开始在代码中对它进行调用(在部署时不要将它们留在..)

如果您怀疑它是表单加载,请为表单添加事件处理程序(加载,激活等)(如果它们不存在),并添加一些虚拟代码以粘贴调试(或调用您的noddy记录器)。 / p>

这是重要的一点。 优化101

不要猜! 在所有主要方法中粘贴日志调用,查看您被告知的内容然后深入研究。添加更多呼叫,进行更多的配置文件分析,直到您清楚地了解正在发生的事情。

一次进行一次优化,并根据您的基数对其进行基准测试,确保条件相同,使用10条记录比10万条记录要快得多,除非您不需要其他记录。 9990 ...

在优化时很容易破坏你的代码,所以准备好一些测试,以确保你没有真正快速地提出错误的答案。

选择你的目标,不要花费一个星期的时间来关闭一个只能在十年内运行一次的功能。

最重要的是,除非您发现9990记录,否则您不需要类型问题,请记住优化是一种权衡。例如,如果在运行应用程序时自动实例化所有表单,则推迟它们直到选择菜单项。目前这是一个启动延迟,然后是真正的快速,推迟,将使你更快开始,但功能将需要更长的时间。延迟和缓存会增加程序的复杂性。

另外一个优化很容易与另一个优化冲突,所以你加载所有东西都准备好了,但是你从那里做的一切都很慢,因为你耗尽了大部分的可用内存....

HTHS

答案 4 :(得分:0)

这是一个超级迟到的答案,不确定它是否仍然相关。作为大型dll和ocx的作者,我也遇到了这个问题。我唯一接受的是,我认为它与注册公共类有关,并且它们将通过VB6调试库重定向。当应用程序完成时,它仍然需要一些时间才能返回IDE,但是,时间差不多。可能是因为删除注册表项并不像添加它们那样多。这就是为什么你的DLL有性能问题,而不是你的大型exe。