Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 显式导入是否能够减少编译文件的大小?_Haskell - Fatal编程技术网

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

Haskell 显式导入是否能够减少编译文件的大小?,haskell,Haskell,我要问一下有用性。这是关于对已编译的可执行文件/库的大小的影响。不是关于代码的可维护性或可读性 导入特定模块 从包中导入唯一使用的模块而不是导入主模块(主模块本身导入子模块)是否有用 例如,对于外部模块(仅包含导入列表): 而不是: import Foreign import Foreign.ForeignPtr 显式导入函数/类型 只导入使用过的函数/类型而不是导入整个模块是否有用 例如: import Foreign.ForeignPtr (ForeignPtr, mallocForei

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

导入特定模块 从包中导入唯一使用的模块而不是导入主模块(主模块本身导入子模块)是否有用

例如,对于
外部
模块(仅包含导入列表):

而不是:

import Foreign
import Foreign.ForeignPtr
显式导入函数/类型 只导入使用过的函数/类型而不是导入整个模块是否有用

例如:

import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr)
而不是:

import Foreign
import Foreign.ForeignPtr

如果模块被编译为一个对象文件,那么就不是了,甚至在理论上也不是。无法导入的函数仍然可以在内部使用,您可以在
GHCI
中加载模块并测试未导入的内部函数

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

在编译动态库时,理论上可以排除静态分析证明无法通过导出接口的任何可能调用直接或间接访问的代码路径或数据段。如果是这样,编译器可以使用导出列表来证明库中的某个标识符完全无用,并将其排除在已编译的库之外

如果你问一些特定的编译器,比如GHC8,会做什么,我不知道。你得测试一下,看看


特别列出您的导出和导入的主要好处是,几年后,当第二个模块声明您已经在使用的标识符时,您将永远不会遇到麻烦。我以前也遇到过这种情况,现在我更加小心了。

您是否尝试过用两种不同的方式编译一个简单的应用程序,看看是否有不同?我的怀疑是,如果你在没有优化的情况下编译,并且在优化的情况下大小相同,你会得到更大的文件。但你可能需要LTO。我不认为一次显式导入函数和一个模块会有什么区别,这不是Haskell代码的特点;这是链接的一个特点。首先,如果你动态链接,这些都不会有什么不同,所以我假设你说的是静态链接。在第一种情况下,它仅在启用时才有影响;否则,将链接整个库。在第二种情况下,它永远不会有什么不同;从模块导入任何名称(!)都需要在整个模块(或未启用
split objs
的整个包)中进行链接。@user2407038谢谢您的回答!让它成为一个真实的答案,我会验证它。@user2407038怎么样?文档中说它比
splitobjs
@user2407038更有效,如果没有使用名称或类实例(在可执行文件中)或重新导出(在库中),该怎么办?有人可能只想为类型族和没有严格字段的类型导入模块。