2012-03-03 93 views
0

什麼將是C#的背景下,最好的辦法是字符串,消耗更少的空間,UINT64或C#

  1. 在C#中,我使用的字典。我希望它使用更少的內存空間。什麼會更好?

    一個字典,其中的密鑰類型是Uint64或密鑰類型是string?在這兩種情況下,值都是一個自定義類,對於每個字典都是相同的。

    我已宣佈字典如下,

    private static readonly Dictionary<string, List<Node>> HashTable = 
        new Dictionary<string, List<Node>>(); 
    

    類節點被定義爲如下,

    public class Node 
    { 
        public UInt64 CurrentIndex { get; set; } 
        public string NextHashedString { get; set; } 
        public int NextHashPos { get; set; } 
    } 
    

    字符串的鍵實際上是從一個字符串散列值計算如下, 字符串的長度可能爲1到20個字符。

    static UInt64 CalculateHash(string read, bool lowTolerance) 
    { 
        UInt64 hashedValue = 0; 
        int i = 0; 
        while (i < read.Length) 
        { 
         hashedValue += read.ElementAt(i) * (UInt64)Math.Pow(31, i); 
         if (lowTolerance) i += 2; 
         else i++; 
        } 
        return hashedValue; 
    } 
    

    現在,我想存儲此散列值作爲字典的關鍵。什麼是最好的主意。我使用Uint64或將其轉換爲字符串並將字符串用作字典鍵。 我的主要目標是字典使用最小空間和搜索時間的關鍵是更快。

  2. 我有一個3571079個字符的文件。我可以將整個文件讀入一個字符串還是需要高級數據結構?

+1

您尚未提供關於第一種情況的足夠數據。能夠在UInt64密鑰或字符串密鑰之間進行選擇是不尋常的... – 2012-03-03 10:40:37

+0

這個問題對我來說還不清楚......你能提供一些你想要實現的例子嗎? – digEmAll 2012-03-03 10:40:54

+0

@JonSkeet我用snippets修改了這個問題。 – 2012-03-03 10:48:05

回答

3

使用UInt64而不是字符串(或任何其他引用類型)作爲字典的關鍵字實際上會消耗更少的內存。使用像字符串這樣的引用類型需要字典在其內部數據結構中存儲對該鍵的引用,這將引起被引用的對象(字符串)保存在內存中,包括每個對象的開銷等。當鍵是一個UInt64,字典(的當前實現)存儲鍵的值而不是對鍵的引用(作爲泛型操作的常規方式的一部分),而沒有任何單獨的鍵對象。

只有一種情況我可以想到,在某種情況下,UInt64密鑰可能會導致比字符串更高的內存使用量:如果進程是32位(x86),則引用是32位。如果字典很大,但幾乎爲空,則會有很多空的實例Dictionary<K,V>.Entry。對於UInt64鍵,這些實例的關鍵部分將是64位(即使沒有指定明確的值),而對於字符串鍵只有32位。因此,使用UInt64密鑰的字典所分配的內存總量將更多。但這是一個非常理論的情況。

因此,如果您可以在不犧牲其他品質的軟件設計的情況下使用UInt64密鑰而不是字符串,那麼使用它們沒有任何問題。但在真正需要之前不要開始優化。與高德納的話說:「過早的優化是一切罪惡的根源」

更新:因爲你已經更新了您的文章,以顯示你如何UINT64值的計算:

  1. 如果你可以簡單地通過調用UInt64值的ToString來獲得字符串鍵,你首先應該去UInt64版本。通過一切手段它會更有效率。

  2. 使用散列作爲鍵可能有點棘手。你需要確保哈希不會相互碰撞。你的散列函數看起來並不特別好,但這當然取決於你的用例。但我認爲這不在這個問題的範圍之內。

+0

嗨,你是什麼意思「如果字典很大,但幾乎是空的,會有很多空的字典。實體實例」字典將不會爲空。因爲每次我生成一個有效的鍵值對,我將它添加到字典中。 – 2012-03-03 11:00:20

+0

@Pbasak這更多的是在實踐中不會影響你的理論考慮。對於所有實際的應用程序,UInt64鍵將消耗比字符串鍵更少的內存。 – 2012-03-03 11:02:10

+0

實際上這個值是一個節點列表。你可以從代碼中看到。如果出現相同的哈希值,我會將這些節點添加到列表中。 我知道我的散列函數不太好。我就此問了一個單獨的問題。 – 2012-03-03 11:16:49