Я был бы удивлен, если бы в сериализации, используемой кешем AppFabric, использовалось что-то кроме двоичного средства записи из WCF, поэтому, если это так (как это выглядит), то разница объясняется обработкой массивов в двоичный формат. Массивы для определенных типов примитивов имеют специальный тип узла , который позволяет очень эффективно хранить их в двоичном формате. int (и byte) - некоторые из этих типов. Guid нет (я не знаю, что команда выбрала, чтобы решить, будет ли это «тип массива» или нет). Так что, хотя сериализация массива целых чисел в двоичном формате очень эффективна, сериализация массива Guid - нет.
Как предложил m0sa, вы можете преобразовать его в байт [], и вы, вероятно, увидите значительное улучшение. Я обнаружил, что синтаксис LINQ, хотя и намного чище, не дает вам больших улучшений производительности, которые вы можете получить с более традиционным циклом for. Я запустил приведенный ниже код для сравнения скоростей сериализации (которые, я думаю, будут отображаться в кэш AF), и сериализация в виде байта [] (даже с преобразованием между Guid [] в byte []) даже быстрее, чем тот из 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);
}
}