哪个占用更少的空间,UInt64或C#中的字符串

时间:2012-03-03 10:38:18

标签: c# string data-structures dictionary 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 个答案:

答案 0 :(得分:3)

使用UInt64而不是字符串(或任何其他引用类型)作为字典的键实际上会消耗更少的内存。使用引用类型像字符串要求字典存储参照键,在它的内部数据结构,这将导致所引用的对象(字符串)要被保存在存储器中,以及,包括每个对象的开销等。当键是一个UInt64,(当前实现)字典存储键的值而不是对键的引用(作为泛型如何工作的正常方式的一部分),没有任何单独的键对象。

我只能想到一种情况,UInt64密钥可能会导致比字符串更高的内存使用量:如果进程是32位(x86)引用是32位。如果字典很大,但几乎为空,那么会有许多空的Dictionary<K,V>.Entry实例。对于UInt64键,这些实例的关键部分将是64位(即使没有指定显式值),而对于字符串键,它只是32位。因此,对于具有UInt64键的字典,分配的内存总量将更多。但这是一个非常理论化的情况。

因此,如果您可以使用UInt64键而不是字符串而不牺牲软件设计的其他品质,那么使用它们并没有错。但是在真正需要之前不要开始优化。用Donald Knuth的话来说:“过早的优化是所有邪恶的根源”

更新:您已更新帖子以显示您的UInt64值的计算方式:

  1. 如果您只是通过在UInt64值上调用ToString来派生字符串键,那么您应该首先使用UInt64版本。一定会更有效率。

  2. 使用哈希作为密钥可能有些棘手。您需要确保散列不会发生碰撞。您的哈希函数在第一眼看上去并不是特别好,但这当然取决于您的用例。但是,我认为这超出了这个问题的范围。

相关问题