Haskell:模块导入不必要的二进制增长 [英] Haskell: unnecessary binary growth with module imports

查看:83
本文介绍了Haskell:模块导入不必要的二进制增长的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  import Mymodule $ b当我将一个(大)模块导入到主模块中时$ b将合格的MyModule导入为M 
import Mymodule(MyDatatype)

与当我不导入该模块时相比,数量相同。无论我在主模块中是否使用该模块内的任何内容,都会发生这种情况。不应该编译器(我在Debian测试中使用GHC)只在二进制文件中添加运行它所需的内容?

在我的具体情况下,我有一个巨大的Map在MyModule中我不使用主模块。选择性地导入我真正需要的内容,并没有改变编译好的二进制文件的增长。

列表仅用于可读性和避免名称冲突;它们并不会影响链接的内容。



另外,即使您只从库中导入了一些函数,它们仍可能依赖于大部分库中,所以你不一定期望看到一般的仅仅使用一些可用接口的大小减少。



默认情况下,GHC链接整个库,而不仅仅是你使用的部分;你可以通过构建带有GHC的 -split-objs 选项的库(或者把 split-objs:True 在你的cabal-install配置文件中(Unix上的〜/ .cabal / config )),但是会降低编译速度,GHC开发者似乎不推荐这样做: p>


-split-objs



告诉链接器将通常生成的单个对象文件拆分为多个对象文件,每个顶层Haskell函数或者在模块中输入一个。这仅适用于库,这意味着与库链接的可执行文件较小,因为它们仅链接到它们需要的对象文件。然而,分别组装所有部分是昂贵的,所以这比编译通常慢。此外,库自身的大小(.a文件)可能是2到2.5倍的因素。我们使用此功能来构建GHC的库。



- GHC手册


这会省略你使用的库的未使用部分,不管你输入什么。



你可能也有兴趣使用共享Haskell库


When i import a (big) module into a Main module in one of the following ways:

import Mymodule
import qualified Mymodule as M
import Mymodule (MyDatatype)

the compiled binary grows the same huge amount compared to when i don't import that module. This happens regardless of whether i use anything inside that module or not in the Main module. Shouldn't the compiler (i am using GHC on Debian Testing) only add into the binary what is needed to run it?

In my specific case i have a huge Map in Mymodule which i don't use in the Main module. Selectively importing what i really need, did not change the growth of the compiled binary.

解决方案

As far as GHC is concerned, import lists are only there for readability and avoiding name clashes; they don't affect what's linked in at all.

Also, even if you did only import a few functions from a library, they might still depend on the bulk of the library internally, so you shouldn't necessarily expect to see a size decrease from only using some of an available interface in general.

By default, GHC links in entire libraries, rather than only the pieces you use; you could avoid this by building libraries with the -split-objs option to GHC (or put split-objs: True in your cabal-install configuration file (~/.cabal/config on Unix)), but it slows down compilation, and is seemingly not recommended by the GHC developers:

-split-objs

Tell the linker to split the single object file that would normally be generated into multiple object files, one per top-level Haskell function or type in the module. This only makes sense for libraries, where it means that executables linked against the library are smaller as they only link against the object files that they need. However, assembling all the sections separately is expensive, so this is slower than compiling normally. Additionally, the size of the library itself (the .a file) can be a factor of 2 to 2.5 larger. We use this feature for building GHC’s libraries.

The GHC manual

This will omit unused parts of libraries you use, regardless of what you import.

You might also be interested in using shared Haskell libraries.

这篇关于Haskell:模块导入不必要的二进制增长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆