Serializing Guid [] for quickly saving binary files in C # AppFabric

I am trying to read and write arrays of guides in the AppFabric cache. My profiler shows that it serializes this in Xml, which means that everything is going too slow. A Guid[20000] takes 60 ms to add the cache, while an int[80000] size with the same size takes 10 ms. I believe that a Guids array must necessarily look like a byte array somewhere inside. What is the fastest way to get to this by creating as little meta fuzz as possible? I know where I will add and receive to / from the cache, and the data will not be particularly stable, so I do not need to serialize the class information.

+4
source share
2 answers

I would be surprised if the serialization used by the AppFabric cache used nothing but a binary writer from WCF, so if that is the case (it looks like this), the difference is due to the processing of arrays in binary format. Arrays for certain primitive types have a special type node , which allows them to be effectively stored in binary format. int (and byte) are some of these types. Guid is not (I don’t know that the team decided to decide what type of array it would be or not). Therefore, when serializing an array of integers in binary format is very efficient, serializing an array of Guid is not.

As suggested by m0sa, you can convert it to byte [], and you are likely to see a significant improvement. I found out that LINQ syntax, although much cleaner, does not give you the big performance improvements you can get with a more traditional loop. I executed the code below to compare serialization speeds (which I think will be displayed in the AF cache) and serialization as a byte [] (even with conversion between Guid [] to byte []) is even faster than one of int [].

 public class StackOverflow_6346646 { static void SerializeGuid() { Console.WriteLine("Serializing Guid[]"); var guids = new Guid[20000]; Random rndGen = new Random(); for (int i = 0; i < guids.Length; i++) { guids[i] = Guid.NewGuid(); } MemoryStream ms = new MemoryStream(); Stopwatch watch = new Stopwatch(); DataContractSerializer dcs = new DataContractSerializer(guids.GetType()); XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms); watch.Start(); dcs.WriteObject(binaryWriter, guids); binaryWriter.Flush(); watch.Stop(); Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position); } static void SerializeInt() { Console.WriteLine("Serializing int[]"); var guids = new int[80000]; // new Guid[20000]; Random rndGen = new Random(); for (int i = 0; i < guids.Length; i++) { guids[i] = rndGen.Next(); // Guid.NewGuid(); } MemoryStream ms = new MemoryStream(); Stopwatch watch = new Stopwatch(); DataContractSerializer dcs = new DataContractSerializer(guids.GetType()); XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms); watch.Start(); dcs.WriteObject(binaryWriter, guids); binaryWriter.Flush(); watch.Stop(); Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position); } static void SerializeGuidAsByteArray(bool useLinq) { Console.WriteLine("Serializing Guid[] as byte[], {0}", useLinq ? "using LINQ" : "not using LINQ"); var guids = new Guid[20000]; Random rndGen = new Random(); for (int i = 0; i < guids.Length; i++) { guids[i] = Guid.NewGuid(); } MemoryStream ms = new MemoryStream(); Stopwatch watch = new Stopwatch(); DataContractSerializer dcs = new DataContractSerializer(typeof(byte[])); XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms); watch.Start(); byte[] bytes; if (useLinq) { bytes = guids.SelectMany(x => x.ToByteArray()).ToArray(); } else { bytes = new byte[guids.Length * 16]; for (int i = 0; i < guids.Length; i++) { byte[] guidBytes = guids[i].ToByteArray(); Buffer.BlockCopy(guidBytes, 0, bytes, 16 * i, 16); } } dcs.WriteObject(binaryWriter, bytes); binaryWriter.Flush(); watch.Stop(); Console.WriteLine("Serialized in {0}ms, total size = {1} bytes", watch.ElapsedMilliseconds, ms.Position); } public static void Test() { SerializeGuid(); SerializeInt(); SerializeGuidAsByteArray(true); SerializeGuidAsByteArray(false); } } 
+4
source

Use a guid. ToByteArray ()

 Guid[] yourArray = ...; byte[][] serializedArray = yourArray.Select(x => x.ToByteArray()).ToArray(); 

You can even serialize it into a 1-dimensional array, since the length of the Guid (16) byte array is known:

 byte[] serializedArray = yourArray.SelectMany(x => x.ToByteArray()).ToArray(); 
+2
source

All Articles