Запуск XmlSerializer ОГРОМНАЯ потеря производительности на 64-битных системах
Я испытываю действительноОГРОМНЫЙ потеря производительности при вызове простого XmlSerializer.Deserizlize () для класса с большим количеством полей.
НОТАЯ пишу код без Visual Studio, дома, поэтому он может иметь некоторые ошибки.
Мой сериализуемый класс плоский и имеет сотни полей:
[Serializable]
class Foo
{
public Foo() { }
[XmlElement(ElementName = "Field1")]
public string Field1;
// [...] 500 Fields defined in the same way
[XmlElement(ElementName = "Field500")]
public string Field500;
}
Мое приложение десериализует входную строку (даже небольшую):
StringReader sr = new StringReader(@"<Foo><Field1>foo</Field1></Foo>");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
object o = serializer.Deserialize(sr);
При запуске приложения в 32-битных системах (или с 32-битным принудительным использованием corflags.exe), код занимает околоОДНУ СЕКУНДУ в первый раз (генерация временного класса сериализации и все ...), затем он близок к 0.
Запуск приложения в 64-битных системах, код занимаетОДНА МИНУТА в первый раз, то это близко к 0.
Что может повесить системув течение столь длительного времениво время первого выполнения XmlSerializer для большого класса в 64-битной системе?
Прямо сейчас я не уверен, должен ли я винить создание / удаление временного класса, инициализацию таблицы имен XML, CAS, Windows Search, Антивирус или Санта-Клауса ...
Спойлеры
Вот мои тесты, не читайте это, если вы не хотите, чтобы меня отвлекали мои (возможные) ошибки анализа.
Выполнение кода из отладчика Visual Studio делает код быстрым даже в 64-битных системах.Добавление (полностью недокументированного) параметра system.diagnostic «XmlSerialization.Compile», который не позволяет системе удалять временные классы сериализации, делает код быстрым даже в 64-битных системах.Взяв временный класс FooXmlSerializer, созданный во время выполнения, включая .cs в моем проекте, и используя его вместо XmlSerializer, вы заставите код работать БЫСТРО даже в 64-битных системах.Создание того же класса FooXmlSerializer с sgen.exe, включая .cs в моем проекте, и использование его вместо XmlSerializer делает код быстрым даже в 64-битных системахСоздание того же класса FooXmlSerializer с помощью sgen.exe, обращение к сборке Foo.XmlSerializers.dll в моем проекте и использование его вместо XmlSerializer заставляет код работать медленно даже в 64-разрядных системах (это меня очень беспокоит)Потеря производительности происходит только в том случае, если вход для десериализации фактически содержит поле большого класса (это также сильно меня беспокоит)Чтобы дополнительно объяснить последний пункт, если у меня есть класс:
[Serializable]
class Bar
{
public Bar() { }
[XmlElement(ElementName = "Foo")]
public Foo Foo; // my class with 500 fields
}
Десериализация происходит медленно только при передаче потомка Foo. Даже если я уже выполнил десериализацию:
StringReader sr = new StringReader(@"<Bar></Bar>");
XmlSerializer serializer = new XmlSerializer(typeof(Bar));
object o = serializer.Deserialize(sr); // FAST
StringReader sr = new StringReader(@"<Bar><Foo><Field1>foo</Field1></Foo></Bar>");
XmlSerializer serializer = new XmlSerializer(typeof(Bar));
object o = serializer.Deserialize(sr); // SLOW
РЕДАКТИРОВАТЬ Я забыл сказать, что проанализировал выполнение с помощью Process Monitor, и я не вижу ни одной задачи, отнимающей много времени из моего приложения, или из csc.exe, или чего-либо, связанного с Framework. Система просто делает другие вещи (или я что-то упускаю), такие как антивирус, explorer.exe, индексация поиска Windows (уже пытались отключить их)