Improve performance of XmlSerializer

风格不统一 提交于 2019-12-05 04:43:58

Ultimately, it depends on the complexity of your model. XmlSerializer needs to do a lot of thinking, and the fact that it is taking so long leads me to suspect that your model is pretty complex. For a simple model, it might be possible to manually implement the deserialization using LINQ-to-XML (pretty easy), or maybe even XmlReader (if you are feeling very brave - it isn't easy to get 100% correct).

However, if the model is complex, this is a problem and frankly would be very risky in terms of introducing subtle bugs.

Another option is DataContractSerializer which handles xml, but not as well as XmlSerializer, and certainly not with as much control over the layout. I strongly suspect that DataContractSerializer would not help you.

There is no direct replacement for XmlSerializer that I am aware of, and if sgen.exe isn't an option I believe you basically have options:

  • live with it
  • rewrite XmlSerializer yourself, somehow doing better than them
  • use something like LINQ-to-XML and accept the effort involved

Long term, I'd say "switch formats", and use xml for legacy import only. I happen to know of some very fast binary protocols that would be pretty easy to substitute in ;p

The problem is that you are requesting types which are not covered by sgen which results in the generation of new assemblies during startup.

You could try to get your hands on the temp files generated by Xmlserializer for your specific types and use this code for your own pregnerated xmlserializer assembly. I have used this approach to find out why csc.exe was executed which did delay startup of my application.

Besides this it might help to rename some types like in the article to arrive at the same type names that sgen is creating to be able to use sgen. Usually type arrays are not precreated by sgen which is a pitty sometimes. But if you name your class ArrayOf HereGoesYourTypeName then you will be able to use the pregenerated assemblies.

you have to Deserialize your list using a classic .net Serialization

something like the below:

TextReader tr = new StreamReader("yourlist.xml"); 
XmlSerializer serializer = new XmlSerializer(typeof(List<YourObject>));
List<YourObject> myCutomList = (List<YourObject>)serializer.Deserialize(tr); 
tr.Close(); 

then you can use the Json.Serialization

JavaScriptSerializer json = new JavaScriptSerializer();
JsonResult output = json.Serialize(myCutomList );

If you have xml stored in the format that you cannot use then use xslt to transform it to the format that you can use.

If this xml is stored in the XmlSerializer format - lets say in flat files - or a db - then you can run your transforms over it once and not incur the XmlSerializer overhead at your usual runtime.

Alternatively you could xslt it at run time - but I doubt that this would be faster than the method outlined by Massimiliano.

Peter Wishart

This answer has some good info on why XmlSerializer runs slow with XmlAttributeOverrides.

Do you really need to use the XmlSerializer in your main thread at startup?

Maybe run it in a background thread; If only some parts of the data are mandatory for startup perhaps you could manually read them into proxy/sparse versions of the real classes while the XmlSerializer initializes.

If its a GUI app you could just add a splash screen to hide the delay (or a game of tetris!!)

If all else fails can't you convert the existing files to JSON by just running the existing deserialize and a JSON serialize, or is there a hard requirement to keep them XML?

You can use threading or tasks to get the application to startup faster and don't wait for the hardrive or the deserialization.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!