在某些情况下,选择静态链接而不是动态链接或反之,是否有令人信服的性能原因?我听过或读过以下内容,但我对这个主题了解不够,无法保证其真实性。

1)静态链接和动态链接在运行时性能上的差异通常可以忽略不计。

如果使用使用概要数据优化程序热路径的分析编译器,2)(1)是不正确的,因为使用静态链接,编译器可以优化你的代码和库代码。使用动态链接,只能优化您的代码。如果大部分时间都花在运行库代码上,这可能会有很大的不同。否则,(1)仍然适用。


当前回答

1/我曾经参与过一个项目,其中动态链接和静态链接是基准测试,差异并没有小到可以切换到动态链接(我没有参与测试,我只知道结论)

2/ Dynamic linking is often associated with PIC (Position Independent Code, code which doesn't need to be modified depending on the address at which it is loaded). Depending on the architecture PIC may bring another slowdown but is needed in order to get benefit of sharing a dynamically linked library between two executable (and even two process of the same executable if the OS use randomization of load address as a security measure). I'm not sure that all OS allow to separate the two concepts, but Solaris and Linux do and ISTR that HP-UX does as well.

3/我在其他项目中使用了动态链接的“简单补丁”功能。但是这个“简单补丁”使得小补丁的发布更加容易,而复杂补丁的发布则成为版本控制的噩梦。因为错误的版本是token,我们经常不得不推送所有内容,并在客户站点跟踪问题。

我的结论是,我使用静态链接除外:

比如依赖于动态链接的插件 当共享是重要的(大型库被多个进程同时使用,如C/ c++运行时,GUI库,…它们通常是独立管理的,ABI对此有严格的定义)

如果有人想使用“简单的补丁”,我认为库必须像上面的大库一样管理:它们必须几乎独立,具有定义好的ABI,不能被修复更改。

其他回答

在类unix系统上,动态链接会使“root”很难使用安装在偏僻位置的共享库的应用程序。这是因为对于具有根权限的进程,动态连接器通常不会注意LD_LIBRARY_PATH或其等效内容。有时,静态链接可以解决问题。

另外,安装过程必须确定库的位置,但这可能会使计算机上的多个软件版本难以共存。

这真的很简单。当您在源代码中进行更改时,您希望等待10分钟或20秒来构建它?我只能忍受20秒。除此之外,我要么拿出剑来,要么开始考虑如何使用单独的编译和链接将其带回舒适区。

执行静态链接构建的一个原因是验证可执行文件是否完全关闭,即所有符号引用都正确解析。

作为使用持续集成构建和测试的大型系统的一部分,夜间回归测试使用可执行文件的静态链接版本运行。偶尔,我们会看到一个符号无法解析,静态链接会失败,即使动态链接的可执行文件可以成功链接。

这种情况通常发生在共享库中位置较深的符号有拼写错误的名称,因此不能进行静态链接时。无论使用深度优先还是宽度优先求值,动态链接器都不能完全解析所有符号,因此您可以完成一个没有完全闭包的动态链接可执行文件。

另一个尚未讨论的问题是修复库中的错误。

使用静态链接,您不仅需要重新构建库,还必须重新链接和重新分发可执行文件。如果库只在一个可执行文件中使用,这可能不是问题。但是,需要重新链接和重新分发的可执行文件越多,痛苦就越大。

使用动态链接,只需重新构建和重新分发动态库,就完成了工作。

静态链接将程序需要的文件包含在一个可执行文件中。

动态链接是你通常会考虑的,它使一个可执行文件仍然需要dll等在同一个目录(或者dll可以在系统文件夹中)。

(动态链接库)

动态链接的可执行文件编译速度更快,资源也不那么繁重。