【发布时间】:2014-10-03 23:54:32
【问题描述】:
我们的应用程序正在读取一些 XML 文件。 XML 格式是固定的,因此我们可以使用XmlSerializer 轻松读取它们。
我使用此代码读取 XML 文件并将它们转换为类:
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;
}
但是,存在一些性能问题。第一次调用此代码时,使用 T 的特定类型时,XmlSerializer 会生成一个 Project.XmlSerializer.dll 文件。
这很好,但要花费一些宝贵的毫秒时间(在我的情况下大约是 900 毫秒)。这可以通过使用XML Serializer Generator (sgen) 在正手上生成该程序集来规避。这将时间减少到大约一半。主要是由于程序集的读取和反射。
我想进一步优化这一点,将XmlSerializer 类带入实际类所在的程序集中,但我找不到让XmlSerializer 知道不要阅读的方法外部程序集,但使用当前程序集的序列化程序。
任何想法如何做到这一点或使这项工作的替代方法? (我无法预加载它们,因为大多数序列化的类都是在启动时使用的)
使用 ANTS Profiler 的分析(来自其他机器的指标,但模式相同):
简单。大多数时间(300 毫秒 + 400 毫秒 = 700 毫秒)都浪费在生成和加载 XmlSerializer 程序集的过程中。
使用 sgen 生成程序集。大多数时间(336 毫秒)都在加载 XmlSerializer 程序集时丢失。
当在项目中包含程序集的实际源代码并直接调用序列化程序时,动作会下降到 456 毫秒(第一次是 1 秒,第二次是 556 毫秒)。
【问题讨论】:
-
与问题无关:您不需要
reader.Close();,因为 using 语句通过Dispose为您执行此操作。 -
我无法理解您在开头的最后一段中的意思我想通过引入 XmlSerializer 类来进一步优化它... 你能说清楚一点吗?那我试试看:)
-
如果加载 dll 是您感觉的唯一问题。您可以打开文件并立即关闭它(应用程序启动后立即在另一个线程中)(如果您知道路径)。操作系统会将文件缓存在缓存中,以便下次尝试读取文件(通过 clr)将很快。忘记我是否在不理解你的情况下说了一些愚蠢的话:(
-
单次执行是您的应用正常运行的方式吗?如果生成/加载程序集需要很长时间,并且您的应用程序多次使用 FromXml,您应该进行更实际的性能测试,在其中反序列化各种数据以查看实际反序列化性能。
-
用户设置在启动时读取并在关闭时保存。还有一些其他的 xml 文件通常具有相同的模式。 (顺便说一句,第二次确实很快,但我想尽量减少启动时间)
标签: c# .net performance xml-serialization