Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving a Dictionary<String, Int32> in C# - Serialization?

I am writing a C# application that needs to read about 130,000 (String, Int32) pairs at startup to a Dictionary. The pairs are stored in a .txt file, and are thus easily modifiable by anyone, which is something dangerous in the context. I would like to ask if there is a way to save this dictionary so that the information can be reasonably safely stored, without losing performance at startup. I have tried using BinaryFormatter, but the problem is that while the original program takes between 125ms and 250ms at startup to read the information from the txt and build the dictionary, deserializing the resulting binary files takes up to 2s, which is not too much by itself but when compared to the original performance is a 8-16x decrease in speed.

Note: Encryption is important, but the most important should be a way to save and read the dictionary from the disk - possibly from a binary file - without having to use Convert.ToInt32 on each line, thus improving performance.

like image 906
Miguel Avatar asked Oct 26 '10 08:10

Miguel


People also ask

How do I convert a dictionary to a JSON string in C#?

We do this, because both the Key and Value has to be of type string, as a requirement for serialization of a Dictionary . var json = new JavaScriptSerializer(). Serialize(convertedDictionary); //You can then serialize the Dictionary, as both the Key and Value is of type string, which is required for serialization.

How to get values of dictionary in C#?

Values Property. This property is used to get a collection containing the values in the Dictionary<TKey,TValue>. Return Value: This property returns a collection containing the Values in the Dictionary.

How dictionaries work in C#?

A dictionary, also called an associative array, is a collection of unique keys and a collection of values, where each key is associated with one value. Retrieving and adding values is very fast. Dictionaries take more memory because for each value there is also a key.

Can C# dictionary have different data types?

C# Dictionary class constructor takes a key data type and a value data type. Both types are generic so it can be any . NET data type. The following Dictionary class is a generic class and can store any data type.


1 Answers

interesting question. I did some quick tests and you are right - BinaryFormatter is surprisingly slow:

  • Serialize 130,000 dictionary entries: 547ms
  • Deserialize 130,000 dictionary entries: 1046ms

When I coded it with a StreamReader/StreamWriter with comma separated values I got:

  • Serialize 130,000 dictionary entries: 121ms
  • Deserialize 130,000 dictionary entries: 111ms

But then I tried just using a BinaryWriter/BinaryReader:

  • Serialize 130,000 dictionary entries: 22ms
  • Deserialize 130,000 dictionary entries: 36ms

The code for that looks like this:

public void Serialize(Dictionary<string, int> dictionary, Stream stream)
{
    BinaryWriter writer = new BinaryWriter(stream);
    writer.Write(dictionary.Count);
    foreach (var kvp in dictionary)
    {
        writer.Write(kvp.Key);
        writer.Write(kvp.Value);
    }
    writer.Flush();
}

public Dictionary<string, int> Deserialize(Stream stream)
{
    BinaryReader reader = new BinaryReader(stream);
    int count = reader.ReadInt32();
    var dictionary = new Dictionary<string,int>(count);
    for (int n = 0; n < count; n++)
    {
        var key = reader.ReadString();
        var value = reader.ReadInt32();
        dictionary.Add(key, value);
    }
    return dictionary;                
}

As others have said though, if you are concerned about users tampering with the file, encryption, rather than binary formatting is the way forward.

like image 96
Mark Heath Avatar answered Oct 13 '22 18:10

Mark Heath