我有一個dictionary<string, int[]>
,我需要儘可能有效地從磁盤存儲和檢索。在C#中存儲/檢索字典的最有效方法?
密鑰長度(字符串)通常會在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:請將您的評論轉換爲答案,以便我可以將其標記爲已批准。
「有效地」你的意思是「尺寸效率」? – Stefan
@Stefan - 大小/速度似乎不是一個問題,因爲OP將它存儲在文本文件中......但的確需要知道什麼類型的「規模足夠好」才需要回答。 –
很少有旁註;而不是讓你的列表在循環之外並不斷清理它,只需在循環內定義列表。分割一個沒有分隔符的字符串只會返回一個大小爲1的數組,因此您不需要檢查字符串是否包含',',只是每次都分割並將所有值添加到列表中,即使「全部」只是一個。你需要對數組進行排序嗎?如果您正在重新創建現有結構,爲什麼他們還沒有排序? – Servy