<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://forums.lhotka.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'Lists', 'ReadOnlyBase', 'LoadProperty', 'Performance', and '.NET 4'</title><link>http://forums.lhotka.net/search/SearchResults.aspx?s=5&amp;o=DateDescending&amp;tag=Lists,ReadOnlyBase,LoadProperty,Performance,.NET+4&amp;orTags=0</link><description>Search results matching tags 'Lists', 'ReadOnlyBase', 'LoadProperty', 'Performance', and '.NET 4'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP3 (Build: 36.8414)</generator><item><title>Performance of LoadProperty Method</title><link>http://forums.lhotka.net/forums/p/11336/52645.aspx#52645</link><pubDate>Fri, 27 Apr 2012 17:11:14 GMT</pubDate><guid isPermaLink="false">49a2225a-bd1e-4c5d-a665-720b81e87ca9:52645</guid><dc:creator>rlhiggin</dc:creator><description>&lt;p&gt;Hi folks,&lt;/p&gt;
&lt;p&gt;My team is working on a WPF application using CSLA 4.2.1 for our business layer implementation. We have one area within our application that currently displays a list of 5633 info objects. This list is taking approximately 3.0 seconds to load. So, I decided to investigate in order to determine what the bottleneck is. I discovered that the culprit is in the LoadProperty(IPropertyInfo propertyInfo, object newValue) method on ReadOnlyBase&amp;lt;T&amp;gt; that is being called to populate the objects from a data reader.&lt;/p&gt;
&lt;p&gt;This particular info object has 33 fields which means that LoadProperty is being called 5633 * 33 or 185,889 times in order to create the list we are trying to display. Upon further inspection, I discovered that this LoadProperty method is doing some pretty heavy lifting via reflection in order to set the field manager properties. I also noticed that a lot of this heavy lifting could be done during type initialization rather than each time a property is loaded.&lt;/p&gt;
&lt;p&gt;I wanted to try this idea out to see if it would work and to see whether or not the performance would improve noticeably. What I came up with was this:&lt;/p&gt;
&lt;p&gt;&lt;blockquote style="overflow-x: scroll;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;/p&gt;
&lt;p&gt;public class MyInfoObject : ReadOnlyBase&amp;lt;MyInfoObject&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static readonly Dictionary&amp;lt;IPropertyInfo, System.Reflection.MethodInfo&amp;gt; genericPropertyMethods;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static MyInfoObject()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods = new Dictionary&amp;lt;IPropertyInfo, MethodInfo&amp;gt;();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var methods = typeof(MyInfoObject).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var loadPropertyMethod = methods.FirstOrDefault(x =&amp;gt; x.Name == &amp;quot;LoadProperty&amp;quot; &amp;amp;&amp;amp; x.IsGenericMethod);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var cslaPropertyFields = typeof(MyInfoObject).GetFields(BindingFlags.Static | BindingFlags.NonPublic).Where(x =&amp;gt; x.FieldType.GetGenericTypeDefinition().IsAssignableFrom(typeof(Csla.PropertyInfo&amp;lt;&amp;gt;).GetGenericTypeDefinition()));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in cslaPropertyFields)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var current = (IPropertyInfo)(item.GetValue(null));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods.Add(current, loadPropertyMethod.MakeGenericMethod(new[] { current.Type }));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void LoadProperty(IPropertyInfo propertyInfo, object newValue)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods[propertyInfo].Invoke(this, new[] { propertyInfo, newValue });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;The goal here is that instead of creating a generic method to access the property storage every time LoadProperty is called, we create all of the generic methods that will be needed one time at type intialization via a static constructor. We then store those methods in a static dictionary so they can be accessed by all instances of the type. Finally, the LoadProperty method is overridden to look up and invoke methods that are stored in the static dictionary rather than using the base implementation which would run through all the reflection code again.&lt;/p&gt;
&lt;p&gt;The results of this experiment were exactly what I expected -- faster performance. The time to load the list was reduced from approximately 3.0 seconds to approximately 1.0 seconds.&lt;/p&gt;
&lt;p&gt;This particular scenario was just a test that I setup within our system to gauge performance for loading larger lists. We will have other objects that have roughly the same number of properties that get loaded from the database and may eventually have 10-20x as many records returned once the software is fielded. In the interest of keeping our architecture scalable, we are considering implementing this logic in a generic base class such as this:&lt;/p&gt;
&lt;p&gt;&lt;blockquote style="overflow-x: scroll;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;/p&gt;
&lt;p&gt;public class CustomReadOnlyBase&amp;lt;T&amp;gt; : ReadOnlyBase&amp;lt;T&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static readonly Dictionary&amp;lt;IPropertyInfo, System.Reflection.MethodInfo&amp;gt; genericPropertyMethods;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static CustomReadOnlyBase()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods = new Dictionary&amp;lt;IPropertyInfo, MethodInfo&amp;gt;();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var loadPropertyMethod = methods.FirstOrDefault(x =&amp;gt; x.Name == &amp;quot;LoadProperty&amp;quot; &amp;amp;&amp;amp; x.IsGenericMethod);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var cslaPropertyFields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.NonPublic).Where(x =&amp;gt; x.FieldType.GetGenericTypeDefinition().IsAssignableFrom(typeof(Csla.PropertyInfo&amp;lt;&amp;gt;).GetGenericTypeDefinition()));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in cslaPropertyFields)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var current = (IPropertyInfo)(item.GetValue(null));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods.Add(current, loadPropertyMethod.MakeGenericMethod(new[] { current.Type }));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void LoadProperty(IPropertyInfo propertyInfo, object newValue)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; genericPropertyMethods[propertyInfo].Invoke(this, new[] { propertyInfo, newValue });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;This would allow all of our business objects to have the same behavior. Because of the way .NET handles static members in generic types, I believe that at run time, each read only business object type, T, would get it&amp;#39;s own generic type, CustomReadOnlyBase&amp;lt;T&amp;gt; , which means we would have one static dictionary of methods for each read only business object.&lt;/p&gt;
&lt;p&gt;The fact that this implementation is not already in the CSLA ReadOnlyBase&amp;lt;T&amp;gt; makes me question whether or not this is actually a good idea. The performance benefit in my test scenario was obvious, but I&amp;#39;m curious if there are any other implications that I may have overlooked.&lt;/p&gt;
&lt;p&gt;So, while this thread was mostly intended to be a discussion, I do still have 2 questions:&lt;/p&gt;
&lt;p&gt;1.) Is there a better way to get the performance increase that we are looking for?&lt;/p&gt;
&lt;p&gt;2.) Is there a reason the reflection code was being run in every single call to LoadProperty rather than one time for type initialization? Or, to reword this question, is there a reason I should not create a CustomReadOnlyBase&amp;lt;T&amp;gt; with this implementation?&lt;/p&gt;</description></item></channel></rss>