2011-06-14 1 views
4

Guides 배열을 읽고 AppFabric 캐시에 쓰려고합니다. 내 프로파일 러는 XML에 이것을 직렬화하고 있다는 것을 보여 주며 이는 너무 느리게 진행된다는 것을 의미합니다. Guid[20000]은 비슷한 크기의 int[80000]이 10ms를 소요하는 반면 캐시에 추가하려면 60ms가 걸립니다. Guids의 배열이 반드시 내부적으로 바이트 배열처럼 보일 것임을 알았습니다. 가능한 빨리 메타 보풀을 만드는 동안 가장 빠른 방법은 무엇입니까? 캐시를 추가하고 캐시에서 가져 오는 위치를 알고 데이터가 특히 영구적으로 처리되지 않으므로 클래스 정보를 serialize하는 것에 신경을 쓰지 않습니다.Guid []를 C# AppFabric에 저장하기 위해 신속하게 이진 파일로 변환

답변

4

나는 직렬화 경우 놀랠 것입니다 AppFabric 캐시에서 사용하는 WCF의 이진 작성자 이외의 다른 것을 사용 했으므로이 경우 (이 경우처럼)이 경우에는 이진 형식의 배열 처리로 차이가 설명됩니다. 특정 기본 유형의 배열에는 special node type이있어 매우 효율적으로 이진 형식으로 저장할 수 있습니다. int (및 byte)는 이러한 유형 중 일부입니다. Guid는 (나는 "어레이 타입"이 될 것인지 아닌지를 결정하기 위해 팀이 선택한 것을 모른다.) 따라서 이진 형식의 정수 배열을 직렬화하는 것은 매우 효율적이지만 Guid 배열을 직렬화하는 것은 쉽지 않습니다.

m0sa가 제안 했으므로 이것을 []으로 변환하면 큰 개선이있을 것입니다. 나는 LINQ 문법이 훨씬 더 깨끗하지만,보다 전통적인 for 루프로 얻을 수있는 큰 성능 향상을주지 못한다는 것을 발견했다. 직렬화 속도 (AF 캐시에 매핑 될 것입니다)와 바이트 [] (심지어 Guid [] 사이의 변환이 바이트 []) 로의 직렬화를 비교하기 위해 아래 코드를 실행했습니다. 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); 
    } 
} 
2

Guid를 사용하십시오. ToByteArray()

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

당신은 알려진 가이 바이트 배열의 길이 때문에, 1 개 차원 배열로 (16) 직렬화도 수 :

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