【发布时间】:2016-04-04 13:52:41
【问题描述】:
为了进行单元测试,我必须导出许多小的内部类,这些类从未打算供我的 DLL 的客户端使用。
我知道每个导出的函数都会在可执行映像中产生一个存根,如果 DLL 未在其首选位置加载,Windows 加载程序必须对这些存根执行修复。
有人建议将 DLL 构建为静态库,仅用于单元测试。
我想知道这是否值得麻烦?我找不到任何关于从 DLL 导出每个类的问题可能有多大的参考,或者如果我有选择性的话,加载器性能和内存消耗是否有任何显着提升。
我想我在某处读到 GCC 编译器默认导出所有内容。
编辑:由于该问题的陈述动机是有争议的,让我改写一下: 我是否应该检查我的 DLL 并删除所有未向其客户端公开的类上的 DLLEXPORT?假设我正在使用一堆遗留 DLL,我注意到它们有很多不必要的导出。这会提高加载速度吗?特别是在使用 MSVC 版本 9+ 的 Windows 7 和 8 上。
【问题讨论】:
-
这是一种代码味道。如果您可以检测到您的代码失败的唯一方法是访问内部,那么普通的客户端程序员怎么能检测到它呢?或者你只是在测试错误的东西,只测试客户端程序员将使用的公共 api。
-
@HansPassant 我们正在做 TDD - 自下而上构建,管理层的要求是每一层代码都必须有一组单元测试,即使它不直接暴露给客户端.事实上,我们并不确切知道最终的公共 API 会是什么。
-
不太可能造成可衡量的性能损失。但你总是可以试试看。设置也应该很容易,以便只有调试版本包含这些导出。
-
是的,但如果我错了,请纠正我,它们都是按序号导出的,因此它减少了 dll 大小,并且在绑定时不会发生查找/字符串搜索。好文章:blog.omega-prime.co.uk/?p=115
-
显而易见的“成本”是您的 DLL 会因两个原因而变大。首先,链接器不能丢弃这些类的任何成员函数,因为它们都将被使用(通常,它可以丢弃任何未调用或完全内联的成员函数)。其次,导出表将大得多,因为它将包含所有附加导出的修饰名称字符串。较大的 DLL 会消耗更多的地址空间。我预计除了大小开销之外,不会有太多可衡量的性能影响。
标签: windows performance dll