在2d字典中保存数据?

时间:2014-11-06 21:52:27

标签: c# linq dictionary

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);

虽然它有效,但它非常慢(并且看起来也不是特别好)。

哪种方法更好?

5 个答案:

答案 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