静态链接与动态链接

新手上路,请多包涵

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

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

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

原文由 Eloff 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答
  • 动态 链接可以 减少总资源消耗(如果多个进程共享同一个库(当然包括“相同”中的版本))。我相信这是推动它在大多数环境中存在的论点。这里的“资源”包括磁盘空间、RAM 和缓存空间。当然,如果您的动态链接器不够灵活,则存在 DLL hell 的风险。
  • 动态 链接意味着错误修复和库升级可以 传播 以改进 您的 产品,而无需您交付任何东西。
  • 插件 总是需要 动态 链接。
  • 静态 链接意味着您可以知道代码将在非常 有限的环境 中运行(在引导过程的早期,或在救援模式下)。
  • 静态 链接可以使二进制文件 更容易分发 到不同的用户环境(以发送更大、更消耗资源的程序为代价)。
  • 静态 链接可能允许稍微 更快的启动 时间,但这在某种程度上取决于程序的大小和复杂性 以及 操作系统加载策略的细节。

一些编辑以在评论和其他答案中包含非常相关的建议。我想指出,你打破这个的方式很大程度上取决于你计划在什么环境中运行。最小的嵌入式系统可能没有足够的资源来支持动态链接。稍微大一点的小系统可能很好地支持动态链接,因为它们的内存足够小,使得动态链接节省的 RAM 非常有吸引力。正如 Mark 指出 的那样,成熟的消费类 PC 拥有大量资源,您可能会让便利性问题推动您对此事的思考。


解决性能和效率问题: 这取决于.

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

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

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

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

回答性能问题的方法 始终 是通过测试(并尽可能使用像部署环境一样的测试环境)。

原文由 dmckee — ex-moderator kitten 发布,翻译遵循 CC BY-SA 4.0 许可协议

Static linking 是编译时的一个过程,将链接的内容复制到主二进制文件中并成为单个二进制文件。

缺点:

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

Dynamic linking 是加载链接内容时的运行时进程。该技术允许:

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

缺点:

  • 开始时间较慢(应复制链接的内容)
  • 运行时引发链接器错误

[iOS 静态与动态框架]

原文由 yoAlex5 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题