将Dictionary<string, int[][]>
和Dictionary<int, Dictionary<string, string>
中的数据存储到文件中的最快方法是什么,以后可以将其导入并转换回变量?
目前,我使用这样的代码(这是针对Dictionary<string, int[][]>
):
string saveString = "";
int i = 0;
foreach (KeyValuePair<string, int[][]> entry in data)
{
if (i > 0)
saveString += "|";
saveString += entry.Key + ":";
int j = 0;
foreach (int[] x in entry.Value)
{
if (j > 0)
saveString += ";";
int k = 0;
foreach (int y in x)
{
if (k > 0)
saveString += ",";
saveString += y;
k++;
}
j++;
}
i++;
}
string dir = Path.Combine(Directory.GetCurrentDirectory(), Config.saveDirectory, Config.saveName);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
File.WriteAllText(Path.Combine(dir, "data.txt"), saveString);
虽然它有效,但它非常慢(并且看起来也不是特别好)。
哪种方法更好?
答案 0 :(得分:2)
你不是在看好地方。 存储数据不,获取数据
。以您的示例为例,int[30][30]
条目最少50条(如果我看起来正确,则为〜91600字符串连接),最多需要6600毫秒!不涉及存储,只有连接部分。问题是,每次你追加到你的字符串时,你需要从0开始并一直到一直到最后,浪费了很多时间。
您可以阅读Joel Spolsky的Schlemiel the Painter's algorithm以了解有关该现象的更多信息。
要解决此问题,只需使用StringBuilder
,即可针对这些用例。使用完全相同的数据集,它可以将操作从6600ms加速到仅6ms。
所以你的初始例子,现在使用StringBuilder:
StringBuilder saveString = new StringBuilder();
int i = 0;
foreach (KeyValuePair<string, int[][]> entry in data)
{
if (i > 0)
saveString.Append("|");
saveString.Append(":");
int j = 0;
foreach (int[] x in entry.Value)
{
if (j > 0)
saveString.Append(";");
int k = 0;
foreach (int y in x)
{
if (k > 0)
saveString.Append(",");
saveString.Append(y);
k++;
}
j++;
}
i++;
}
string dir = Path.Combine(Directory.GetCurrentDirectory(), Config.saveDirectory, Config.saveName);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
File.WriteAllText(Path.Combine(dir, "data.txt"), saveString.ToString());
答案 1 :(得分:0)
不使用串联字符串,而是使用StringBuilder。
StringBuilder saveString = new StringBuilder();
...
saveString.Append(...); // Instead of saveString += ..
...
File.WriteAllText(Path.Combine(dir, "data.txt"), saveString.ToString());
答案 2 :(得分:0)
查看序列化。 .NET Framework有几个内置实现:Binary,XML,Json。您也可以尝试Protobuf-net。
答案 3 :(得分:0)
DataContractJsonSerializer
处理字典和锯齿状数组:
// setting up sample data
var data = new Dictionary<string, int[][]>();
int[][] x = new int[][] {new int[]{1,2,3},new int[]{4,5,6}};
data["One"] = x;
x = new int[][] {new int[]{11,12,13},new int[]{24,25,26}};
data["Two"] = x;
// serialization starts here:
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Dictionary<string, int[][]>));
ser.WriteObject(stream1, data);
结果如下:
[{"Key":"One","Value":[[1,2,3],[4,5,6]]},{"Key":"Two","Value":[[11,12,13],[24,25,26]]}]
要反序列化,只需致电ReadObject
:
// reusing the original stream for demonstration purposes - it reality this would be a new stream
stream1.Position = 0;
var data2 = (Dictionary<string, int[][]>)ser.ReadObject(stream1);
答案 4 :(得分:0)
我建议使用JSON而不是发明自己的标记。序列化\反序列化JSON最受欢迎的库之一是Newtonsoft.JSON