我有一个dictionary<string, int[]>
我需要尽可能有效地从磁盘存储和检索的文件。
密钥长度(字符串)通常会在 1 到 60 个字符(unicode)之间变化,但可能会超过该长度(但是这是边际的,这些值可以被丢弃)。数组中的整数将在 1 到 1 亿之间。(通常为 1 到 5M)
我的第一个想法是使用分隔格式:
key [tab] int,int,int,int,...
key2 [tab] int,int,int,int,...
...
并按如下方式加载字典:
string[] Lines = File.ReadAllLines(sIndexName).ToArray();
string[] keyValues = new string[2];
List<string> lstInts = new List<string>();
// Skip the header line of the index file.
for (int i = 1; i < Lines.Length; i++)
{
lstInts.Clear();
keyValues = Lines[i].Split('\t');
if (keyValues[1].Contains(','))
{
lstInts.AddRange(keyValues[1].Split(','));
}
else
{
lstInts.Add(keyValues[1]);
}
int[] iInts = lstInts.Select(x => int.Parse(x)).ToArray();
Array.Sort(iInts);
dic.Add(keyValues[0], iInts);
}
它可以工作,但是考虑到潜在的大小要求,很明显这种方法永远无法很好地扩展。
这个问题是否有现成的解决方案,还是我需要完全重新设计算法?
编辑:我有点不好意思承认,但我不知道字典可以序列化为二进制。我给了它一个测试运行,它几乎是我需要的。
这是代码(欢迎提出建议)
public static void saveToFile(Dictionary<string, List<int>> dic)
{
using (FileStream fs = new FileStream(_PATH_TO_BIN, FileMode.OpenOrCreate))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, dic);
}
}
public static Dictionary<string, List<int>> loadBinFile()
{
FileStream fs = null;
try
{
fs = new FileStream(_PATH_TO_BIN, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
return (Dictionary<string, List<int>>)bf.Deserialize(fs);
}
catch
{
return null;
}
}
对于一个包含 100k 条目的字典,每个条目包含一个 4k 整数数组,序列化需要 14 秒,反序列化需要 10 秒,结果文件为 1.6gb。
@Patryk:请将您的评论转换为答案,以便我将其标记为已批准。