Napisałem program do serializacji klasy "Person" przy użyciu XMLSerializer, BinaryFormatter i ProtoBuf. Myślałem, że protobuf-net powinien być szybszy od pozostałych dwóch. Serializacja Protobuf była szybsza niż XMLSerialization, ale znacznie wolniejsza od serializacji binarnej. Czy moje zrozumienie jest nieprawidłowe? Proszę, pomóż mi to zrozumieć. Dziękuję za pomoc.protobuf-net NIE działa szybciej niż serialowanie binarne?
EDYCJA: - Zmieniłem kod (zaktualizowany poniżej), aby zmierzyć czas tylko dla serializacji i nie tworząc strumieni i nadal widzę różnicę. Czy możesz mi powiedzieć, dlaczego?
Poniżej znajduje się wyjście: -
Osoba został stworzony przy użyciu buforu protokołu w 347 milisekund
Osoba został stworzony przy użyciu języka XML w 1462 milisekund
Osoba został stworzony przy użyciu binarnego w 2 milisekundy
Kod poniżej
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
namespace ProtocolBuffers
{
class Program
{
static void Main(string[] args)
{
string folderPath = @"E:\Ashish\Research\VS Solutions\ProtocolBuffers\ProtocolBuffer1\bin\Debug";
string XMLSerializedFileName = Path.Combine(folderPath,"PersonXMLSerialized.xml");
string ProtocolBufferFileName = Path.Combine(folderPath,"PersonProtocalBuffer.bin");
string BinarySerializedFileName = Path.Combine(folderPath,"PersonBinary.bin");
if (File.Exists(XMLSerializedFileName))
{
File.Delete(XMLSerializedFileName);
Console.WriteLine(XMLSerializedFileName + " deleted");
}
if (File.Exists(ProtocolBufferFileName))
{
File.Delete(ProtocolBufferFileName);
Console.WriteLine(ProtocolBufferFileName + " deleted");
}
if (File.Exists(BinarySerializedFileName))
{
File.Delete(BinarySerializedFileName);
Console.WriteLine(BinarySerializedFileName + " deleted");
}
var person = new Person
{
Id = 12345,
Name = "Fred",
Address = new Address
{
Line1 = "Flat 1",
Line2 = "The Meadows"
}
};
Stopwatch watch = Stopwatch.StartNew();
using (var file = File.Create(ProtocolBufferFileName))
{
watch.Start();
Serializer.Serialize(file, person);
watch.Stop();
}
//Console.WriteLine(watch.ElapsedMilliseconds.ToString());
Console.WriteLine("Person got created using protocol buffer in " + watch.ElapsedMilliseconds.ToString() + " milliseconds ");
watch.Reset();
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(person.GetType());
using (TextWriter w = new StreamWriter(XMLSerializedFileName))
{
watch.Start();
x.Serialize(w, person);
watch.Stop();
}
//Console.WriteLine(watch.ElapsedMilliseconds.ToString());
Console.WriteLine("Person got created using XML in " + watch.ElapsedMilliseconds.ToString() + " milliseconds");
watch.Reset();
using (Stream stream = File.Open(BinarySerializedFileName, FileMode.Create))
{
BinaryFormatter bformatter = new BinaryFormatter();
//Console.WriteLine("Writing Employee Information");
watch.Start();
bformatter.Serialize(stream, person);
watch.Stop();
}
//Console.WriteLine(watch.ElapsedMilliseconds.ToString());
Console.WriteLine("Person got created using binary in " + watch.ElapsedMilliseconds.ToString() + " milliseconds");
Console.ReadLine();
}
}
[ProtoContract]
[Serializable]
public class Person
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public Address Address { get; set; }
}
[ProtoContract]
[Serializable]
public class Address
{
[ProtoMember(1)]
public string Line1 { get; set; }
[ProtoMember(2)]
public string Line2 { get; set; }
}
}
kilka szybkich notatek - Najpierw spróbuj zmniejszyć wpływ czynników zewnętrznych na twój test. Serialize do strumienia pamięci lub innego względnie względnie neutralnego celu, a nie systemu plików. Po drugie, powinieneś tylko wykonać operację serializacji - nie włączaj tworzenia strumieni lub konstrukcji obiektów. Po trzecie, powtórz testy w rozsądnej liczbie razy i zgłoś zagregowane wyniki. –
Dzięki za komentarze. Wspomniałeś "raczej cel neutralny pod względem wydajności niż system plików". Co to znaczy? czy mógłbyś podać przykłady "względnie neutralnego celu"? Dziękuję Ci. –
@Ashish - Myślałem głównie o strumieniu pamięci. Środowisko * może * nadal * wpływać na twoje testy, jeśli serializujesz do strumienia pamięci (na przykład presja pamięci może zmusić Cię do przejścia do pamięci wirtualnej dla jednego testu, a nie dla drugiego), ale myślę, że byłby mniej prawdopodobny wpływ na twoje wyniki niż system plików. Z perspektywy czasu ** ważniejsze jest, aby powtórzyć swoje testy, niż próbować uzyskać absolutnie neutralne warunki testowe **, ale dążenie do tych warunków nie zaszkodzi. ;) –