Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Improvements for IVarGet / IVarSet #1393

Open
VolkmarR opened this issue Nov 25, 2023 · 5 comments
Open

Performance Improvements for IVarGet / IVarSet #1393

VolkmarR opened this issue Nov 25, 2023 · 5 comments

Comments

@VolkmarR
Copy link
Contributor

I did some experiments to find a way to improving the performance of IVarGet and IVarSet. These methods use reflection to get and set property and field values (GetValue and SetValue).

I created a benchmark project with faster alternatives called GetValueFast and SetValueFast. These methods create Lambda Expressions to get/set values of public accessible properties and fields. The implementation is inspired by this blogpost: https://blog.zhaytam.com/2020/11/17/expression-trees-property-getter/

Can you try, if these replacement methods can be used in IVarGet and IVarSet (and other places, where GetValue/SetVaue calls are made)?

GetSetValueFast.zip

@RobertvanderHulst
Copy link
Member

Volkmar, thanks for the suggestions. We will look into this.

@cpyrgas
Copy link

cpyrgas commented Nov 28, 2023

Thanks for the info, wasn't aware of this possibility and it looks very promising! It does have a much higher initial overhead, but subsequent calls are more than 10 times faster than pure reflection.

Found a bigger bottleneck though, when IVarGet/Put is used for fields, OOPHelpers.FindProperty() is always called no matter what here

var propInfo := OOPHelpers.FindProperty(t, cIVar, true, lSelf)
and here
var propInfo := OOPHelpers.FindProperty(t, cIVar, false, lSelf)
, and always tries to find the member as property with reflection and that's where 70% of the time is lost.

I think we can cache also the non-existence of the property, but will further investigate. After that, will look into also using the lambda expressions

@VolkmarR
Copy link
Contributor Author

VolkmarR commented Nov 28, 2023

Thanks for the feedback. I missed the initial performance hit because of a mistake in the benchmark... I should have cleared the cache before every invocation. That changes the situation and it is probably be a bad idea to use this method for every property/field.

But it could be interesting for properties, that are called very often. Maybe a manual registration of specific properties could be an option. Or some usage statistics, that trigger the generation after a certain number of calls.

I updated the benchmark project GetSetValueFastNew.zip

@cpyrgas
Copy link

cpyrgas commented Nov 28, 2023

Volkmar, well the overhead is still less than some miliseconds, so it might be still worth it. But more speed will be gained by the optimization I mentioned.

Btw, have you analyzed your system's performance and found that those functions really slow it down? Because in my system you can do millions such operations per second, at least that's the cost of the function themselves. But of course if the property called does something heavy, then all the time is spent there..

I might get a little slow in responding, feeling like I'm getting the flu. Argh, again...

@VolkmarR
Copy link
Contributor Author

No, I didn't analyze our system performance. But I know, that we have a lot of late-bound code in our project. So I thought that by improving IVarGet/Put i could get performance improvements of the whole system a little bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants