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 optimization #170

Closed
tomasherceg opened this issue May 1, 2016 · 2 comments
Closed

Performance optimization #170

tomasherceg opened this issue May 1, 2016 · 2 comments

Comments

@tomasherceg
Copy link
Member

We need to define some perf test cases and try to make things faster.

  1. Client-side performance: GridView with 1000 rows and 30 columns.
@exyi
Copy link
Member

exyi commented Aug 11, 2016

DotVVM Properties runtime performance

Reading and writing to dotvvm properties are actually quite costy at runtime and property dictionaries also consume quite a lot of memory and stress the GC. I propose few optimizations on them:

Store them in simple sequential list instead of dictionary

I have measured Dictionary<TKey, TValue> vs List and when the key is object compared by reference (like DotvvmProperties are) the Dictionary beats List only if the property count is > greater then ~30. This will probably rarely happen in normal dotvvm control. Maybe we could also try different hash table implemetation, Dictionary<TKey, TValue> is probably too generic.

Store internal and common properties in normal fields

Properties like UniqueID could be stored in separate field. But I'm not very sure, if this one will help.

Little Bloom filter for properties

Lot of finds in the property table result in "nothing found", e.g. when walking DataContext stack and lot of properties are rarely set and almost always return default value.
We could add single Int64 field to the property collection that will act as little 64-bit bitmap and every DotvvmProperty will have it's 64-bit mask with about 4 bits set to 1. When property is set it will or the property's map with the object's filter propertyFiter |= property.FilterMask. On read we could simply (probabilistically) check if the property is set by checking if all the mask bits are set: if ((propertyFilter & property.FilterMask) == property.FilterMask)

Prototypes

Most of the properties are set on control initialization by the generated control builder and never changed later -- maybe we could have one prototype property array, that could be overwritten by the actual one in the object, similarly like object prototypes work in JS. I'm not very sure how exactly could we implement it, but it could save a lot of memory allocation.

Control tree

Every request to the DotVVM page the entire control tree has to be built. It is a lot of allocation and maybe could be eliminated a bit.

Don't build "dummy controls" on postbacks

We can probably skip building of control that certainly don't interact with anything and don't contain command binding -- HtmlGenericControl and Literal should be save to skip and are the most common elements of the tree. Of course they'd have to be populated if the Postback.Update is set, but that should not be problematic nor very common.

Optimize controls to RawLiterals at compile time

It should be possible to render simple controls at compile time to simple literals. We should implement HtmlGenericControl and have interface where anyone could connect their renders (that use magic like symbolic execution to figure out what the control renders ;) ).
This optimization can be bit dangerous if some control relies on what in their content is. I'd leave first level descendants and path to root untouched for "blackbox" controls by default, it could be overridden by attribute on the control and by some extensibility interface (for the magic that knows better).

Prototypes?

I'm not very sure if it will be possible for controls, but it could be awesome.

Routing

Large route tables can be surprisingly costy :(. It can especialy hurt if you are loading lot of resources not handled by dotvvm and all the routes have to fail before the request is forwarded to next middleware. It is slow mainly because we use regular expressions to match them and .NET's implementation of them is damn slow. The routing system is quite powerful and I don't want to end up writing custom text matcher. Maybe there already is better implementation, maybe Antlr... For quick fix it should help to extract required prefix for each route and first if the url starts with that string.

@tomasherceg tomasherceg added this to the Future milestone May 23, 2017
@tomasherceg tomasherceg modified the milestones: Version 4.0, Future Jul 20, 2021
@exyi
Copy link
Member

exyi commented Jul 20, 2021

We have spit this into smaller issues with a performance label: https://github.com/riganti/dotvvm/issues?q=is%3Aopen+is%3Aissue+label%3Aperformance

@exyi exyi closed this as completed Jul 20, 2021
@exyi exyi removed this from the Future milestone Jul 29, 2021
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

2 participants