C# 存储“a”的数据类型建议;地段;弦乐?

C# 存储“a”的数据类型建议;地段;弦乐?,c#,.net,hash,dictionary,storage,C#,.net,Hash,Dictionary,Storage,我有一个定期查询数据库的应用程序。它返回多达数百万个字符串,其中绝大多数是bieng重复。我需要将所有这些记录存储在内存中,并尝试将占用的空间最小化 我当前的设计是对每个字符串调用GetHashCode(),然后存储哈希而不是字符串本身 然后我尝试将其添加到字典()结构中。我还保留了第二个字典dictionary(),随着更多条目使用该字符串,该字典将递增\递减 在entries dispose方法中,我减少计数器,如果使用率降至零,则从字典中删除字符串 因此,有几个问题: 这是傻瓜的差事吗?是

我有一个定期查询数据库的应用程序。它返回多达数百万个字符串,其中绝大多数是bieng重复。我需要将所有这些记录存储在内存中,并尝试将占用的空间最小化

我当前的设计是对每个字符串调用GetHashCode(),然后存储哈希而不是字符串本身

然后我尝试将其添加到
字典()
结构中。我还保留了第二个字典
dictionary()
,随着更多条目使用该字符串,该字典将递增\递减

在entries dispose方法中,我减少计数器,如果使用率降至零,则从字典中删除字符串

因此,有几个问题:

这是傻瓜的差事吗?是否有一些数据类型可以比与这个巨人合作节省我大量的时间/精力

我希望我的字符串表是线程安全的(目前不是)。使用ConcurrentDictionary是我的最佳选择吗


提前感谢。

这方面的主要问题是两个不同的字符串可能具有相同的哈希代码

听起来你让事情变得比实际需要的更复杂了。你需要的是拘留:

CLR已经维护了一个字符串实例表以节省内存

更新

然而。。。您应该记住文档中的警告:在CLR卸载之前,不会对插入的字符串进行垃圾收集,也就是说,它们在您的应用程序域的生命周期中一直存在

但您可以轻松地实现相同的模式:

class LocalStringInterner
{
    private Dictionary<string, string> _strings = new Dictionary<string, string>();

    public string Intern(string str)
    {
        string interned;
        if (_strings.TryGetValue(str, out interned))
            return interned;

        _strings.Add(str, str);
        return str;
    }
}
class LocalStringInterner
{
私有字典_strings=新字典();
公共字符串实习生(字符串str)
{
实习;
if(_strings.TryGetValue(str,out interned))
返回实习;
_strings.Add(str,str);
返回str;
}
}
这样,当您不再需要这组字符串时,您可以放弃
LocalStringInterner


为了从多个线程安全使用,您可以将
Intern
的主体包装在
锁(\u strings)

中。主要问题是两个不同的字符串可能具有相同的哈希代码

听起来你让事情变得比实际需要的更复杂了。你需要的是拘留:

CLR已经维护了一个字符串实例表以节省内存

更新

然而。。。您应该记住文档中的警告:在CLR卸载之前,不会对插入的字符串进行垃圾收集,也就是说,它们在您的应用程序域的生命周期中一直存在

但您可以轻松地实现相同的模式:

class LocalStringInterner
{
    private Dictionary<string, string> _strings = new Dictionary<string, string>();

    public string Intern(string str)
    {
        string interned;
        if (_strings.TryGetValue(str, out interned))
            return interned;

        _strings.Add(str, str);
        return str;
    }
}
class LocalStringInterner
{
私有字典_strings=新字典();
公共字符串实习生(字符串str)
{
实习;
if(_strings.TryGetValue(str,out interned))
返回实习;
_strings.Add(str,str);
返回str;
}
}
这样,当您不再需要这组字符串时,您可以放弃
LocalStringInterner


为了确保从多个线程安全使用,您可以将
Intern
的主体包装在
锁(\u strings)

也许md5哈希可以帮助您实现这一点。它(理论上)应该是唯一的,并且受到大多数数据库的支持(如果不是C#将帮助您)

MySQL:

SELECT name, md5(name)
FROM user
P>以上所说的,我会考虑更好的数据库方法。< /P> 如果服务器端的每个字符串都有一个唯一的id,那么这应该是一项简单的任务

假设您有一个名为
string\u resources
的表,其中包含一个自动递增
id
列和一个
varchar
字段。我还将在
value
上添加一个唯一的索引,以确保不会将字符串存储两次

|id     | value          |
|1      | Hello          |
|2      | World          |
...
|145789 | Something else |
现在您可以将int值存储在字典中

md5: 128bit
int32: 32bit  // <-- You Don't Say?
md5:128位

int32:32bit/也许md5哈希可以帮助您实现这一点。它(理论上)应该是唯一的,并且受到大多数数据库的支持(如果不是C#将帮助您)

MySQL:

SELECT name, md5(name)
FROM user
P>以上所说的,我会考虑更好的数据库方法。< /P> 如果服务器端的每个字符串都有一个唯一的id,那么这应该是一项简单的任务

假设您有一个名为
string\u resources
的表,其中包含一个自动递增
id
列和一个
varchar
字段。我还将在
value
上添加一个唯一的索引,以确保不会将字符串存储两次

|id     | value          |
|1      | Hello          |
|2      | World          |
...
|145789 | Something else |
现在您可以将int值存储在字典中

md5: 128bit
int32: 32bit  // <-- You Don't Say?
md5:128位

int32:32bit/我不认为获取哈希代码并将字符串存储在
字典中以及将计数存储在单独的字典中有什么意义。您可以使用字符串本身作为键,字典将自动(在内部)创建和存储哈希代码。因此,只使用一本字典就足够了。您还可以通过
dict.Keys
从字典中检索字符串

两个不同字符串的哈希代码可以相同。这叫做碰撞。
字典
自动处理这些冲突


concurrentDictionary
似乎是合适的;但是,我对它没有任何经验。

我不认为获取哈希代码并将字符串存储在
字典中以及将计数存储在单独的字典中有什么意义。您可以使用字符串本身作为键,字典将自动(在内部)创建和存储哈希代码。因此,只使用一本字典就足够了。您还可以通过
dict.Keys
从字典中检索字符串

两个不同字符串的哈希代码可以相同。这叫做碰撞。Th