Performance comparisons for accessing object properties using expression trees and reflections

Source: Internet
Author: User

Today, at work, you need to get the values of all the properties on the object, but don't know the type of the object beforehand. My first reaction was to use reflection, but this would be done many times, and a lot of reflection would definitely have a performance impact. Although it doesn't matter to me, I chose another solution: Build the expression tree, build the delegate, and then cache the delegate in the dictionary. The code is as follows:

First build the expression tree (similar to this: ' (a) = = A.xx ') and generate the delegate:

Private Static Delegate builddynamicgetpropertyvaluedelegate (PropertyInfo property) {    var ] Instance");     var memberexpression = Expression.property (instanceexpression, property);     var lambdaexpression = Expression.lambda (memberexpression, instanceexpression);     return lambdaexpression.compile ();}

Then, when you need to get the value of the property, first look in the dictionary to see if there are already generated delegates, and some say that the delegate execution gets the property value. No, the build expression tree generates the delegate and puts it into the dictionary:

Private StaticDictionary<propertyinfo, delegate> Delegatecache =NewDictionary<propertyinfo, delegate>(); Public Static ObjectGetpropertyvalueuseexpression<tobject>(TObject obj, PropertyInfo property) {if(Delegatecache.containskey (property)) {varFunc = (Func<tobject,Object>) Delegatecache[property]; returnfunc (obj); }    varGetvaluedelegate =Builddynamicgetpropertyvaluedelegate (property); Delegatecache[property]=getvaluedelegate; return(Func<tobject,Object>) (getvaluedelegate) (obj);}

As simple as that, I wanted to test the performance gap between the expression tree version and the reflected version, so I simply implemented the reflection version as a test comparison:

 Public Static Object Getpropertyvalueusereflection<tobject>(TObject obj, PropertyInfo PropertyInfo) {    return  propertyinfo.getvalue (obj);}

Next is the test code for both:

classCar { Public stringMake {Get;Set; }  Public stringModel {Get;Set; }  Public intcapacity {Get;Set; }} .....intRepeatTimes =10000; PropertyInfo Property=typeof(Car). GetProperty (" Make"); Car Car=NewCar (); Stopwatch Stopwatch=stopwatch.startnew (); for(inti =0; i < RepeatTimes; i++) {getpropertyvalueuseexpression (car, property);} Stopwatch. Stop (); Console.WriteLine ("repeated {0}, Cache in Dictionary expression used time: {1} ms", RepeatTimes, stopwatch. Elapsedticks); stopwatch. Reset (); stopwatch. Start (); for(inti =0; i < RepeatTimes; i++) {getpropertyvalueusereflection (car, property);} Stopwatch. Stop (); Console.WriteLine ("repeated {0}, Reflection used time: {1} ms", RepeatTimes, stopwatch. Elapsedticks);

This is what I expected: the expression tree version is slower than the reflection version when the number of calls is low, and the benefits of the expression tree version become more pronounced as the number of times increases.

But the test results were unexpected!!!

In the case of 100,000, million, thousands of calls, the time spent is about the same, and the reflected version is actually faster. It's depressing to me.

Depressed, I was wondering whether because the dictionary causes the same performance, the following test code is added:

stopwatch. Reset (); stopwatch. Start (); var Object>) builddynamicgetpropertyvaluedelegate (property);  for (int0; i < repeattimes; i++) {    func (car);} Stopwatch. Stop (); Console.WriteLine ("repeated {0}, Immediate call expression used time: {1} ticks", RepeatTimes, stopwatch. Elapsedticks);

This part of the test code is called directly after building the expression tree to generate the delegate, removing the effect of the dictionary. The test results are as follows:

Sure enough, the dictionary was removed 10 times times faster.

It seems that the effect of using a dictionary cache delegate in my case is not too good. Do not know if there is a better way to cache the delegate.

Finally, if my code is wrong or the test method is wrong, you are welcome to point out

Performance comparisons for accessing object properties using expression trees and reflections

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.