我有4个dictionarys,包含800k字符串,200到6000个字符。 当我把它加载到内存中它占用大约11演出的内存。 我需要2分钟来解析数据,2分钟才能输出数据。 无论如何输出数据比我下面使用的更快? 我只获得每秒20-31 MB的磁盘IO,我知道硬盘可以做800ish
var hash1 = new Dictionary<int, Dictionary<string, string>>(f.Count + 2);
var hash2 = new Dictionary<int, Dictionary<string, string>>(f.Count + 2);
var hash3 = new Dictionary<int, Dictionary<string, string>>(f.Count + 2);
var hash4 = new Dictionary<int, Dictionary<string, string>>(f.Count + 2);
....
foreach (var me in mswithfilenames)
{
filename = me.Key.ToString();
string filenamef = filename + "index1";
string filenameq = filename + "index2";
string filenamefq = filename + "index3";
string filenameqq = filename + "index4";
StreamWriter sw = File.AppendText(filenamef);
StreamWriter sw2 = File.AppendText(filenameq);
StreamWriter swq = File.AppendText(filenamefq);
StreamWriter sw2q = File.AppendText(filenameqq);
for (i = 0; i <= totalinhash; i++)
{
if (hashs1[i].ContainsKey(filenamef))
{
sw.Write(hashs1[i][filenamef]);
}
if (hashs2[i].ContainsKey(filenameq))
{
sw2.Write(hashs2[i][filenameq]);
}
if (hashs3[i].ContainsKey(filenamefastaq))
{
swq.Write(hash4[i][filenamefastaq]);
}
if (hash4[i].ContainsKey(filenameqq))
{
sw2q.Write(hash4[i][filenameqq]);
}
}
sw.Close();
sw2.Close();
sw3.Close();
sw4.Close();
swq.Close();
sw2q.Close();
}
答案 0 :(得分:3)
你有什么衡量标准吗?听起来你有大量的数据需要读写 - 所以第一步是为你的磁盘子系统建立绝对基线,读取/写入大量数据的速度。简单读取文件,然后写入您预期的大致数据量的新文件,将显示您可以在多大程度上优化它。
您可能会认为您的代码本身不会花费太多时间来阅读/写作。
答案 1 :(得分:2)
最昂贵的部分是I / O.这个循环:
for (i = 0; i <= totalinhash; i++)
{
if (hashs1[i].ContainsKey(filenamef))
{
sw.Write(hashs1[i][filenamef]);
}
if (hashs2[i].ContainsKey(filenameq))
{
sw2.Write(hashs2[i][filenameq]);
}
...
}
在不同文件之间交替。这可能会导致一些额外的头部移动,并且会创建碎片文件(减慢将来对这些文件的操作)。
我会用:
for (i = 0; i <= totalinhash; i++)
{
if (hashs1[i].ContainsKey(filenamef))
{
sw.Write(hashs1[i][filenamef]);
}
}
for (i = 0; i <= totalinhash; i++)
{
if (hashs2[i].ContainsKey(filenameq))
{
sw2.Write(hashs2[i][filenameq]);
}
}
...
但当然你应该衡量这一点。例如,仅在机械磁盘上,它对SSD没有太大影响。
答案 2 :(得分:1)
你能有一个Dictionary<int, Dictionary<string, myCustomDataHolder>>
而不是四个独立的并行Dictionary<int, Dictionary<string, string>
吗?它不仅应该减少占用的空间很多,而且意味着字典查找的1/4。
根据你的问题,字典是否完全平行还不是很清楚,但对我来说似乎已经足够了。
答案 3 :(得分:0)
我想补充一下
if (hashs1[i].ContainsKey(filenamef))
{
sw.Write(hashs1[i][filenamef]);
}
进行2次哈希表访问。一个用于包含密钥,一个用于实际访问。许多字典访问可以加起来,因此您可以使用字典tryGetValue方法将这些访问减半。这将把这两个调用合二为一。我可以解释一下这是如何工作的,但这比我做得更好:http://www.dotnetperls.com/trygetvalue