2012-02-08 31 views
8

當我輸入一個(大)模塊爲主要模塊中的下列方式之一:哈斯克爾:與模塊導入不必要的二進制增長

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

編譯的二進制增長同樣數額巨大時相比,我不不導入該模塊。無論我在主模塊中是否使用該模塊內的任何內容,都會發生這種情況。不應該編譯器(我在Debian測試中使用GHC)只添加到二進制文件中運行它需要什麼?

在我的具體情況下,我在MyModule中有一個巨大的Map,我沒有在Main模塊中使用它。選擇性地導入我真正需要的東西,並沒有改變編譯好的二進制文件的增長。

回答

17

就GHC而言,導入列表僅用於可讀性和避免名稱衝突;它們根本不影響連接的內容。另外,即使你只從庫中導入了一些函數,它們仍然可能依賴於庫的大部分內部,所以你不應該期望看到僅僅使用一些可用的庫一般界面。

默認情況下,GHC鏈接整個庫,而不僅僅是你使用的部分;你可以通過建立圖書館與-split-objs選項GHC避免這種情況(或者把split-objs: True在您的小集團安裝配置文件(~/.cabal/config在UNIX上)),但它會減慢編譯,並且看似未推薦的GHC開發商:

-split-objs

給鏈接器分裂將通常生成到多個目標文件,每個模塊中的頂層的Haskell功能或類型的一個單獨的對象文件。這僅適用於庫,這意味着與庫鏈接的可執行文件較小,因爲它們僅鏈接到它們需要的對象文件。然而,分別組裝所有部分是昂貴的,所以這比編譯通常慢。此外,庫自身的大小(.a文件)可能是2到2.5倍的因素。我們使用這個特性來構建GHC的庫。

- The GHC manual

這將省去您在使用圖書館,無論你輸入什麼樣的未使用的部分。

您可能也有興趣使用shared Haskell libraries

+0

引用ehird:「就GHC而言,導入列表僅用於可讀性和避免名稱衝突;它們完全不影響鏈接的內容。」這不可能是真實的,因爲即使我只在主模塊中放置「import Mymodule」而不在模塊內部使用任何東西,尺寸的增長也會發生。 – Josephine 2012-02-10 10:34:30

+1

「導入列表」是指要在模塊名稱後面括號中導入的標識符列表,而不是模塊頂部的導入語句列表。 – ehird 2012-02-10 13:49:49

+0

對,這很有道理。感謝您的澄清和非常豐富的答案! – Josephine 2012-02-10 20:48:28