我最近開發了一個Rust庫,試圖提供對一個大型數據庫(Unicode字符數據庫,作爲一個平面XML文件是160MB)的快速訪問。我也希望它的佔地面積很小,所以我使用了各種方法來減小尺寸。最終的結果是,我有一系列看起來像靜態切片:靜態數據較重的鏽圖書館似乎臃腫
#[derive(Clone,Copy,Eq,PartialEq,Debug)]
pub enum UnicodeCategory {
UppercaseLetter,
LowercaseLetter,
TitlecaseLetter,
ModifierLetter,
OtherLetter,
NonspacingMark,
SpacingMark,
EnclosingMark,
DecimalNumber,
// ...
}
pub static UCD_CAT: &'static [((u8, u8, u8), (u8, u8, u8), UnicodeCategory)] =
&[((0, 0, 0), (0, 0, 31), UnicodeCategory::Control),
((0, 0, 32), (0, 0, 32), UnicodeCategory::SpaceSeparator),
((0, 0, 33), (0, 0, 35), UnicodeCategory::OtherPunctuation),
/* ... */];
// ...
pub static UCD_DECOMP_MAP: &'static [((u8, u8, u8), &'static [(u8, u8, u8)])] =
&[((0, 0, 160), &[(0, 0, 32)]),
((0, 0, 168), &[(0, 0, 32), (0, 3, 8)]),
((0, 0, 170), &[(0, 0, 97)]),
((0, 0, 175), &[(0, 0, 32), (0, 3, 4)]),
((0, 0, 178), &[(0, 0, 50)]),
/* ... */];
總之,所有的數據應該只需要上漲約600KB最大(假設對齊等額外的空間),但所產生的庫3.3MB處於釋放模式。源代碼本身(幾乎所有的數據)是2.6MB,所以我不明白爲什麼結果會更多。我不認爲額外的大小是固有的,因爲在項目開始時大小爲< 50kB(當時我只有大約2kB的數據)。如果它有所作爲,我還使用#![no_std]
功能。
是否有任何額外的二元膨脹的原因,有沒有辦法縮小尺寸?理論上我不明白爲什麼我不應該把圖書館減少到不超過兆字節或更少。
按照馬蒂厄的建議下,我試着用nm
分析二進制文件。
因爲我所有的表都表示爲借片,這不是計算表的大小,因爲他們都在匿名_ref
很多有益的。我可以確定的是最大地址0x1208f8,這與1MB的文件大小相符,而不是3.3MB。我還通過十六進制轉儲查看是否有任何可能解釋它的空塊,但沒有。
要看看它是否是借來的切片是那樣的問題,我把它們變成非借片([T; N]
形式)。文件大小沒有太大變化,但現在我可以很容易地解釋數據。奇怪的是,表格佔用了我期望的多少(更奇怪的是,它們在不考慮對齊的情況下匹配我的下限,並且表格之間沒有空間)。
我也看了一下有嵌套借片的表, UCD_DECOMP_MAP
以上。當我刪除所有這些數據(大約2/3的數據)時,文件大小應該大約爲1MB〜250kB(通過我的計算和最高的nm
地址0x3d1d0),所以它看起來不像這些表也是問題。
我試圖提取從.rlib文件中的單個文件(這是一個簡單的ar格式的檔案)。事實證明,該庫的40%只是元數據文件,而實際的目標文件是1.9MB。此外,當我沒有借用引用對圖書館這樣做的目標文件是261kB!然後我又回到了原來的庫,並期待在個人_ref
S的大小和發現,對於像UCD_DECOMP_MAP: &'static [((u8,u8,u8),&'static [(u8,u8,u8)])]
一個表,((u8,u8,u8),&'static [(u8,u8,u8)])
類型的每個值佔用24個字節(對於U8三重3個字節,5個字節的填充和16的字節作爲指針),結果這些表佔用了比我想象中更多的空間。我想我現在可以完全考慮所有的文件大小。
當然,3MB還是相當小的,我只是想盡量保持文件小!
有趣的問題,但診斷這將是更容易的分解*什麼*是採取的空間在這裏,這是不明顯的問題(如果再次,我想如果你有故障的問題會是完全不同的)。因此,我不清楚你希望得到什麼樣的答案。 –
@MatthieuM。我想我想知道是否有任何意想不到的事情發生在幕後,以增加使用的空間。我在[類似的庫](https://github.com/huonw/unicode_names)中注意到他對他的數據使用了'#[inline(never)]',但這不再是合法的語法。生鏽可能會將這些數據嵌入到我使用的每個功能中嗎?我可以使用哪些工具/方法診斷圖書館中的空間故障?對不起,如果問題太不清楚,無法回答! – nitrous
在Linux上,我會使用[nm](http://www.thegeekstuff.com/2012/03/linux-nm-command),但是它需要在輸出上使用一些腳本來獲取每個符號的大小並將其分組每個來源的符號。 –