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

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

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


当前回答

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

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

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

其他回答

Dynamic linking can reduce total resource consumption (if more than one process shares the same library (including the version in "the same", of course)). I believe this is the argument that drives its presence in most environments. Here "resources" include disk space, RAM, and cache space. Of course, if your dynamic linker is insufficiently flexible there is a risk of DLL hell. Dynamic linking means that bug fixes and upgrades to libraries propagate to improve your product without requiring you to ship anything. Plugins always call for dynamic linking. Static linking, means that you can know the code will run in very limited environments (early in the boot process, or in rescue mode). Static linking can make binaries easier to distribute to diverse user environments (at the cost of sending a larger and more resource-hungry program). Static linking may allow slightly faster startup times, but this depends to some degree on both the size and complexity of your program and on the details of the OS's loading strategy.


Some edits to include the very relevant suggestions in the comments and in other answers. I'd like to note that the way you break on this depends a lot on what environment you plan to run in. Minimal embedded systems may not have enough resources to support dynamic linking. Slightly larger small systems may well support dynamic linking because their memory is small enough to make the RAM savings from dynamic linking very attractive. Full-blown consumer PCs have, as Mark notes, enormous resources, and you can probably let the convenience issues drive your thinking on this matter.


要解决性能和效率问题:视情况而定。

通常情况下,动态库需要某种粘合层,这通常意味着双重分派或函数寻址中额外的间接层,并且可能会消耗一点速度(但是函数调用时间实际上是运行时间的很大一部分吗??)

但是,如果您正在运行多个进程,并且它们都经常调用同一个库,那么使用动态链接而不是静态链接时,您最终可以节省缓存行(从而赢得运行性能)。(除非现代操作系统足够智能,能够在静态链接的二进制文件中注意到相同的段。似乎很难,有人知道吗?)

另一个问题:加载时间。你需要支付装货费用。你什么时候支付这个费用取决于操作系统的工作方式以及你使用的链接。也许你宁愿推迟支付,直到你知道你需要它。

注意,静态链接与动态链接传统上不是一个优化问题,因为它们都涉及到对目标文件的单独编译。然而,这并不是必需的:原则上,编译器可以最初将“静态库”“编译”到一个摘要的AST表单中,并通过将这些AST添加到为主代码生成的AST中来“链接”它们,从而实现全局优化。我使用的系统都没有做到这一点,所以我不能评论它的工作效果如何。

回答性能问题的方法总是通过测试(并尽可能使用与部署环境相似的测试环境)。

动态链接是满足某些许可要求(如LGPL)的唯一实用方法。

静态链接是在编译时将链接的内容复制到主二进制文件中并变成单个二进制文件的过程。

缺点:

编译时间更长 输出二进制更大

动态链接是在运行时加载链接内容的过程。这项技术允许:

升级链接二进制文件而不重新编译主二进制文件,增加ABI稳定性[关于] 是否有单个共享副本

缺点:

开始时间较慢(应复制链接内容) 链接器错误在运行时抛出

[iOS静态vs动态框架]

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

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

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

动态链接的最佳示例是库依赖于所使用的硬件。在古代,C数学库是动态的,这样每个平台都可以使用所有的处理器功能来优化它。

一个更好的例子可能是OpenGL。OpenGl是一个由AMD和NVidia实现的不同的API。你不能在AMD卡上使用NVidia实现,因为硬件是不同的。因此,你不能静态地将OpenGL链接到你的程序中。这里使用了动态链接,以便为所有平台优化API。