2014-11-06 88 views
0

Dictionary<string, int[][]>Dictionary<int, Dictionary<string, string>中的数据存储到文件中的最快方式是什么?以后可以导入并转换回变量?将数据保存在2d字典中?

目前,我用这样的代码(这是为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

对于工作代码,你可能也有兴趣张贴在[codereview.se] – paqogomez 2014-11-06 21:58:10

+0

您还可能有兴趣在[标志你是一个坏的程序员](http://www.yacoset.com/Home/signs-that-you-re-a-bad-programmer)。第1部分项目#4。作为一个有用的笔记,不是个人的。 :) – paqogomez 2014-11-06 22:01:17

回答

2

你并不看好这个地方。问题是不是存储的数据,它与得到的数据。

就你的例子而言,如果我看起来正确的话,只要有50个条目的int[30][30](〜91600个字符串连接),就需要6600ms!不涉及存储,只有连接部分。问题是,每次你追加到你的字符串时,你都需要从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()); 
+0

谢谢!它真的有所作为。现在只需要一两秒钟,然后花费一分钟! – SnackerSWE 2014-11-06 22:19:30

+0

@SnackerSWE没有问题。但我鼓励你阅读关于字符串如何工作的内部以及为什么连接不好:) – 2014-11-06 22:22:01

0

而不是concackating字符串,使用StringBuilder。

StringBuilder saveString = new StringBuilder(); 
... 
saveString.Append(...); // Instead of saveString += .. 
... 
File.WriteAllText(Path.Combine(dir, "data.txt"), saveString.ToString()); 
0

看序列化。 .NET Framework有几个内置实现:Binary,XML,Json。你也可以尝试Protobuf-net

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

我会建议使用JSON而不是发明自己的标记。并且其中一个用于序列化\反序列化JSON的最受欢迎的库是Newtonsoft.JSON