性能优化使用产生的XmlSerializer类的 [英] Performance optimizing use of generated XmlSerializer class

查看:136
本文介绍了性能优化使用产生的XmlSerializer类的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们必须通过我们的应用程序正在读的那几个XML文件。 XML格式是固定的,因此,我们可以阅读他们很容易与的 XmlSerializer的

We have a few XML files that are being read by our applications. The XML format is fixed, and thus we can read them very easily with XmlSerializer.

我用这个code读取XML文件,并将其转换为类:

I use this code to read the XML files and convert them to classes:

public static T FromXml<T>(this string xml) where T : class
{
    if (string.IsNullOrEmpty(xml))
    {
        return default(T);
    }

    XmlSerializer xmlserializer = new XmlSerializer(typeof(T));

    XmlTextReader textReader = new XmlTextReader(new StringReader(xml));
    textReader.Normalization = false;

    XmlReaderSettings settings = new XmlReaderSettings();

    T value;

    using (XmlReader reader = XmlReader.Create(textReader, settings))
    {
        value = (T)xmlserializer.Deserialize(reader);
    }

    return value;
}

但是,也有一些性能问题。当调用此code,第一次一个特定类型的 T 时,在的XmlSerializer 生成一个 Project.XmlSerializer.dll 文件。

However, there are some performance issues. When calling this code for the first time a specific type for T is used, the XmlSerializer generates a Project.XmlSerializer.dll file.

这是好的,但有些费用precious毫秒(约900毫秒在我的情况)。这可以通过产生的正手的组装,使用的 XML序列发生器(SGEN)。这使向下的时间至约一半。主要是由于装配的阅读和思考。

This is fine, but costs some precious milliseconds (about 900ms in my case). This can be circumvented by generating that assembly on forehand, using the XML Serializer Generator (sgen). This brings down the time to about half. Primarily due to the reading and reflection of the assembly.

我要的进一步优化这一点,通过将的XmlSerializer 类组件的实际类在里面,但我无法找到一个办法让的XmlSerializer 不知道读取外部组件,但使用串行从目前的组件。

I want to optimize this further, by bringing the XmlSerializer classes inside the assembly the actual classes are in, but I can't find a way to let XmlSerializer know not to read an external assembly, but use the serializer from the current assembly.

任何思考如何做到这一点,或另一种方法,使这项工作? (我不能pre-加载它们,因为大多数的序列化类用于在启动时)

Any thoughts how to do this or an alternative way to make this work? (I can't pre-load them since most of the serialized classes are used at start-up)

用蚂蚁探查器(从其他机器的指标,但同样的模式)分析:

The analysis using ANTS Profiler (metrics from other machine, but same pattern):

平原。大部分时间(300毫秒+ 400毫秒= 700毫秒)丢失在产生和装载XmlSerializer的装配

Plain. Most of the time (300ms + 400ms = 700ms) is lost in generating and loading the XmlSerializer assembly.

使用产生SGEN组装。大部分时间(336ms)中丢失加载XmlSerializer的装配

With sgen generated assembly. Most of the time (336ms) is lost in loading the XmlSerializer assembly.

在包括项目内组件的实际来源,并直接调用序列化,动作下降到456ms(是1秒在第一位,556ms第二)。

When including the actual source of the assembly inside the project, and calling the serializer directly, the action goes down to 456ms (was 1s in first, 556ms in second).

推荐答案

除非你正在做的序列化的非常的应用程序启动时,一种方法是强制CLR加载,甚至你使用的任何时间提前的类编译,有可能在一个线程这会在后台运行,一旦你开始你的应用程序。

Unless you are doing the serialization at the very app startup, one way would be to force CLR to load and even compile whatever classes you're using ahead of time, possibly in a thread which would run in background as soon as you've started your app.

喜欢的东西,例如:

foreach (Assembly a in assembliesThatShouldBeCompileed)
    foreach (Type type in a.GetTypes())
        if (!type.IsAbstract && type.IsClass)
        {
            foreach (MethodInfo method in type.GetMethods(
                                BindingFlags.DeclaredOnly |
                                BindingFlags.NonPublic |
                                BindingFlags.Public |
                                BindingFlags.Instance |
                                BindingFlags.Static))
            {
                if (method.ContainsGenericParameters || 
                    method.IsGenericMethod || 
                    method.IsGenericMethodDefinition)
                    continue;

                if ((method.Attributes & MethodAttributes.PinvokeImpl) > 0)
                    continue;

                System.Runtime.CompilerServices
                   .RuntimeHelpers.PrepareMethod(method.MethodHandle);
            }
        }

很奇怪,不过,您的分析似乎表明,没有太大的区别,如果SGEN'd code是在一个单独的程序,而装载似乎是瓶颈。我不知道该图看起来像的情况下,他们在同一个组件?

It's strange, however, that your profiling seems to indicate that there is not much difference if the SGEN'd code is in a separate assembly, while loading seems to be the bottleneck. I wonder how the graph looks like for the case where they are in the same assembly?

这篇关于性能优化使用产生的XmlSerializer类的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆