显式导入是否能够减少编译文件的大小?

时间:2017-12-30 14:19:18

标签: haskell

我会询问有用性。它是关于对已编译的可执行文件/库的大小的影响。不是代码可维护性或可读性。

导入特定模块

从包中导入唯一使用的模块而不是导入主模块(自己导入子模块)是否有用。

例如,使用Foreign模块(仅包含导入列表):

import Foreign.Storable

而不是:

import Foreign

显式导入函数/类型

仅导入已使用的函数/类型而不是导入整个模块是否有用?

例如:

import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr)

而不是:

import Foreign.ForeignPtr

1 个答案:

答案 0 :(得分:1)

如果模块被编译为目标文件,那么不,甚至理论上都没有。无法导入的函数仍可在内部使用,您可以在GHCI中加载模块并测试未导出的内部函数。

如果你是静态链接或使用泛型函数的特定实例,那么理论上编译器应该能够分析这个特定程序无法访问哪些库,并作为一个整体程序优化,削减它们超出可执行文件。 (例如,如果程序使用的唯一列表是Int的列表,则编译器可能只编译泛型函数的部分专用[Int]版本,并且只编译您使用的版本。)但是,它无论您如何声明进口和出口,都应该能够进行与整个程序优化相同的静态分析。

在编译动态库时,理论上可以排除静态分析证明永远无法通过导出的接口进行任何可能的调用而直接或间接到达的代码路径或数据。如果是这样,编译器可以使用导出列表来证明库中的某些标识符完全没用,并将其从编译库中删除。

如果你问一些特定的编译器,比如GHC 8,我不知道。你必须测试它并看看。

专门列出您的导出和导入的主要好处是,多年后,当第二个模块声明您已经使用的标识符时,您将永远不会遇到麻烦。这件事发生在我之前,现在我更加小心了。