2017-07-03 60 views
0

我需要存儲十億個「外觀」,我正在尋找最有效的方式來存儲這些內存使用情況和性能。是什麼,例如,在這些方面的差異爲a1, a2, a3最少的內存使用和最佳的性能

struct Appearance<'a> { 
    identity: &'a u64, 
    role:  &'a str 
} 

struct AnotherAppearance<'a>((&'a u64, &'a str)); 

fn main() { 
    let thing = 42; 
    let hair_color = "hair color"; 
    let a1 = Appearance {identity: &thing, role: &hair_color}; 
    let a2 = AnotherAppearance((&thing, &hair_color)); 
    let a3 = (&thing, &hair_color); 
} 

是否有更好的方法,這樣的結構來工作?另外,有沒有辦法獲得關於a1, a2, a3的詳細信息,以便我可以看到它們在內存中是如何表現出來的?

回答

6

首先,正如Ijedrz指出的那樣,您提出的所有替代方案都具有相同的尺寸。實際上,從編譯器的角度來看,它們都是相同的

如果你是更小的內存大小後,你可能會更好使用像斷:

struct Appearance { 
    identity: u32, 
    role: InternedString, 
} 

首先,u32有4倍十億不同的值,所以你絕對不需要爲u64十億條記錄。除此之外,&u64將與64位機器上的u64大小相同,因此使用它沒有太大意義。一個u32是一半的大小是一個獎金。

除此之外,&str似乎令人難以置信的浪費。我認爲,這將對數據產生兩方面的影響,這種變化的可能性不大。如果還有更多Appearance s比角色更多,最好的辦法就是實習字符串並將字段縮小爲指針(或者更好:一個u32 ID,它通過另一個表進行間接尋址)。標準庫中沒有實際的字符串,但是實現起來並不容易,假設在某個地方找不到某個字符串。這樣的結構(假設InternedStringu32 ID)將是8字節,而不是24字節。

如果性能是您所追求的,那取決於如何使用結構。也就是說,&u64u64慢,所以改變這可能會有所幫助。至於字符串,這取決於你如何使用它。如果您主要進行比較,則實習字符串會更快,因爲您可以將那些與單個比較進行比較;比較常規字符串可能會慢得多,因爲您必須實際查看內容。

+0

很棒,我甚至可以使用u16作爲角色的查找鍵,因爲它們並不多。從理論上講,u64由「身份的守護者」擁有,我認爲引用會反映代碼中的這種行爲。我認爲,如果外觀擁有自己的u64,那麼編譯器不會抱怨如果創建了一個Keeper不知道的實例嗎?當你對一個&u64說'較慢'時,我們談論的速度有多慢? –

+0

@LarsRönnbäck:我不知道慢了多少,但爲了查看或使用該值,您必須執行deref並查看內存中的其他位置。保持本地的東西意味着更少的高速緩存抖動。像幾乎所有與性能有關的問題,都取決於您的具體情況。 –

4

所有三種型號似乎具有相同尺寸:

use std::mem::size_of; 

println!("a1: {}", size_of::<Appearance>());  // a1: 24 
println!("a2: {}", size_of::<AnotherAppearance>()); // a2: 24 
println!("a3: {}", size_of::<(&u64, &str)>());  // a3: 24 

所以我只想用一個是最描述,即Appearance