提高C++应用程序启动速度的方法

6
最近,我的老板要求我提高我们使用C ++编写的应用程序的启动速度。这个应用程序有点大,它使用了200多个dll,Windows需要很长时间才能进入main()函数。我尝试了下面两种方法,但仍然无法让我们的老板满意。
  1. 延迟加载dll http://msdn.microsoft.com/en-us/library/yx9zd12s(VS.80).aspx
  2. 使用EDITBIN修改EXE http://msdn.microsoft.com/en-us/library/xd3shwhf(VS.80).aspx
还有其他方法可以改善吗?提前感谢您的帮助。

2
延迟加载并不是魔法;你还必须确保直到启动后一段时间才使用那些DLL。 - MSalters
2
问一个显而易见的问题,你有对启动进行性能分析吗?那告诉了你什么? - MSalters
7个回答

5

哎呀!减少那些 DLL 数量吧!

当然,如果你在启动时加载了 200 个 DLL,它会产生大量的硬页错误,并且需要很长时间才能启动(就像 3ds max 一样)。

重新考虑你的 DLL 策略。将许多小的 DLL 合并成较大的 DLL。我认为你不需要超过 200 个。

并且观看 Raymond Chen 的 Five Things Every Win32 Programmer Needs to Know


5

为了确定减速的真正原因,您需要对应用程序进行分析。例如,您可能会发现自己在加载某个.dll文件时花费大部分时间在某些初始化例程中。找一个好的分析工具,然后确定瓶颈在哪里。


你能推荐一个用于分析我的应用程序的工具吗?谢谢。 - Yigang Wu
我的最爱工具是VTune。它不是免费的,但你可以下载一个30天的评估副本: http://software.intel.com/en-us/intel-vtune/ - zr.
1
除非分析器知道如何对硬盘进行分析,否则它不会显示任何有趣的内容。 - Hans Passant
确实。听nobugz的话。你不是在尝试找到一些时间关键循环中的瓶颈。问题在于启动。 - Alex Budovski
@nobugz: 我不同意你的说法。如果确实是因为进程进行了大量的I/O而导致启动时间缓慢,那么这将在分析器中可见。你会看到CPU处于空闲状态,并等待某些系统调用完成。 - zr.

2

以下是需要注意的几点:

  • 许多小文件比一些大文件要慢得多。
  • 磁盘访问比内存访问慢得多(DLL 文件需要从磁盘加载)。

在这种情况下,减少 DLL 文件的数量是必须的。也许可以将它们合并,但我猜测这是一个模块化的设计,这意味着它们大多数时候无法合并。

您还可以延迟加载 DLL 文件,在启动程序时只加载必要的 DLL 文件。或者您甚至可以通过先使用必要的 DLL 文件启动程序,然后按使用重要性的顺序加载其他 DLL 文件来延迟加载 DLL 文件。


模块化并不意味着需要大量的DLL。 - Alex Budovski
这是正确的。但是一些模块化设计模式,在您想要更改加载或文件结构时可能会妨碍您。 - Michiel

1
使用惰性构建静态对象。
不要在启动时创建全局对象,像这样:
Foo foo;
Bar bar;

int main()
{
    // Access foo and bar
}

使用以下习语在需要时构建它们:

Foo & foo()
{
    static Foo the_instance;
    return the_instance;
}
Bar & bar()
{
    static Bar the_instance;
    return the_instance;
}

int main()
{
    // Access objects through foo() and bar()
}

如果对象的创建成本很高(例如,需要构建大型查找表或执行繁重的IO操作),这将节省您一些启动时间。

但是,这对于加载那些DLL没有帮助。


1

如果您可以访问dll的代码(或其中一些),则可以寻找候选项以进行静态链接。如果您可以将它们中的一堆转换为静态库,则可以大大加快启动速度。


1

你在这里得到了很好的建议。拥有许多DLL是一种过时的潮流,现在你正在为此付出代价。此外,初始化它们可能会做更多不必要的工作。

有一种简单的方法可以告诉你哪些操作需要时间。在IDE(例如Visual Studio)下启动应用程序,在它启动时按下“暂停”按钮并显示调用堆栈。多次执行此操作。每次,你都会看到它正在做什么,最重要的是,为什么。如果你发现它花费了大量时间在某些你不需要的操作上,那么这就告诉你需要修复什么。


@Thomas:没错,你可能会惊讶于它的有效性:https://dev59.com/mnNA5IYBdhLWcg3whuV_#927773 - Mike Dunlavey

0

一个选择,纯粹是心理战,就是在加载时提供进度条...

如果人们有东西可以看,会分散他们的注意力,并让它“感觉”更快,这就是为什么电梯之间有镜子,服务于多个楼层...

但这不会打败秒表...

另一种选择是重新编写代码,使用更少的DLL。你拥有多少预算(金钱/时间)是下一个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接