The two that I found that and decided to evaluate were Anoop Madhusudanan's ElasticObject and Aaron Powell's Dynamics library.
I set up a test application looking to evaluate performance and syntax. I accessed a handful of nodes, including one array of nodes and it's children. For the hand-built version, I set up a simple set of objects with simple properties and wrote code to extract values from XElements.
I had a bit of trouble with the API for the Dynamics library, but I saw some performance promise, so I went ahead to make modifications and support my needs. I went ahead and forked the project on bitbucket to share my changes here.
For the performance check, my Hand-Built code ended up at 6 milliseconds, Dynamics at 75 ms, and Elastic at 237 milliseconds (I pre-loaded the xml into an XElement and timed the parsing). So, the tradeoff here is time spent coding vs runtime. I don't expect my real usage to have a significant impact on the user's experience, so I'm ok with Dynamic's 12x slowdown for now. If it becomes a problem, I'll have a nice bottleneck to remove for version 2 :).
Here are some syntax comparisons:
Attribute Access | |
Hand-Built | if (t.MizConfig.InstrumentPlatform != "TC") |
ElasticObject | if (t.MizConfig.InstrumentPlatform != "TC") |
Dynamics plus mod | Multi-level nesting was not possible as written, MizConfig was returning a string. Changed code to allowif (t.MizConfig.InstrumentPlatform != "TC") |
Iterating multiple same-named elements | |
Hand-Built | foreach (var ch in t.MizConfig.HWChannels) |
ElasticObject | foreach (var ch in t.MizConfig["HWChannel"]) |
Dynamics | foreach (var ch in t.MizConfig.HWChannels) |
Accessing Value (non-iterator) as a double. Note: hand-built is able to hide extraneous nodes from me | |
Hand-Built | d = t.PusherConfiguration.MaxForwardSpeed; |
ElasticObject | d = double.Parse(~t.PusherConfiguration.Speeds.Record_Speed.Max); |
Dynamics | d = double.Parse(t.PusherConfiguration.Speeds.Record_Speed.Max.Value); |
Dynamics plus mod | d = t.PusherConfiguration.Speeds.Record_Speed.Max.To |
Conditionally dealing with optional children | |
Hand-Built | if(xelement.Element("YoMama") != null) during parsing |
ElasticObject | if (~dyn.MizConfig.YoMama != null) |
Dynamics plus mod | Didn't find an easy was as implemented, probably would have had to do dyn.MizConfig.Element.Element("YoMama") mixing in XElement access. Instead, I modified the code to allowif (dyn.MizConfig.YoMama != null) |
No comments:
Post a Comment