This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi, we have a performance issue with an entity that is used quite heavily in our model. Lets call the entity "A". There are about 25 other entities that reference A. I built an example (but was unable to add it to this post) that adds 25k entries into the table of A and into another table for an entity B. All entities do not have any properties. This is the source code:
I get the following output:
It shows that selecting the As takes about 4.5 seconds while selecting the same amount of Bs only takes 0.2 seconds. If you also log the sql-queries you can see that both are equally fast. This means that creating the 25k As takes significantly longer than selecting the Bs. All this time is "lost" during the creation of the entities and not during the selection. The part "Test 1a" is a workaround that shows that the selection of "As" can be fast if we select only the data but not the entities itself. Is there a possibility that this issue can be speed up in the future? Regards, Dennis |
|
|
Hello Dennis, Just a quick note unrelated to your actual question. I've resolved the issue with attaching files so you should be able to now. Thanks for drawing our attention to this. |
|
|
If I understand you correctly, your concern is that materialising As takes a lot longer than materialising Bs. Is that correct? If so, what is the difference between As and Bs? Does A contain a very large field such as an image blob? Does A have an extremely large number of fields? Does A eager load a collection of other entities? Does A participate in class table inheritance (and therefore incur joins across multiple tables)? |
|
|
The only difference between A and B is that A is refenced by a lot of other classes. As you repaired the upload functionality I was now able to add my sample project. |
|
|
Hello Dennis, We've investigated this in some depth and the issue appears to be a minor BCL performance issue exacerbated by the huge number of associations and the large number of entities. Basically it seems a lot of objects are being promoted to generation 1 and 2, meaning that garbage collection is becoming very expensive. We do not yet know whether we can restructure things so that fewer objects escape from generation 0, but we're not optimistic. Our tests indicate that just instantiating 25000 objects with this many EntityCollections (while keeping all 25000 in a list to prevent them being collected when generation 0 is swept) is quite expensive -- EntityCollections are quite heavyweight objects and this exercise produces and initialises 625000 of them. Here's the figures from my machine:
Here's what's being measured in the "creating" trace:
So just instantiating 25000 of these and keeping them in memory takes 1.8sec. The additional overhead of materialising them from the database is about 0.4sec, of which 0.1sec is irreducible overhead as shown by the EntityX load stats. I have investigated some local optimisations to the EntityCollection which improved the construction time for the extreme entity but not enough to justify the impact on more 'normal' entities. I have some other ideas on more structural optimisations but would need to know more about your use case to know if they would help you. Does your Entity1 commonly use all of these collections, or do they usually remain idle and unpopulated, only used on specific occasions or only present to satisfy LightSpeed's formal requirement for a reverse assocation? |
|
|
Hi, the answer to your question is: Does your Entity1 commonly use a) all of these collections, or b) do they usually remain idle and unpopulated, only used on specific occasions or c) only present to satisfy LightSpeed's formal requirement for a reverse assocation? Most of these connections are c) and some say two oder three would fit into b. Regards, Dennis |
|
|
Thanks for the info. Based on your usage, I've implemented some updates that allow you to have null EntityCollections instead of initialising them:
These EntityCollection fields satisfy LightSpeed's formal need for a reverse association, but avoid the cost of constructing an EntityCollection object. The impact is that such fields are never populated and are therefore unusable. You should therefore make this change only to the collections which are never used. The collections which are used on specific occasions must still be initialised normally, but since there are only two or three of these, the impact on construction time should be much less than with 25 of them. This feature should be considered experimental at this point -- we've given it a reasonable amount of testing, but your real model and usage is much more complex than our test models or your repro code, so you may run into some errors. At the moment this feature is not supported in the designer. We will look at adding designer support once you have evaluated it and determined if it addresses your performance issue. For evaluation and testing purposes you will need to customise the templates, hand-tweak the generated code or convert the associations to manual implementation. We will discuss designer options with you if this change meets your needs. This feature will be in the next nightly build, available from about 1200 GMT. |
|
|
I forgot to say, if the entity which has the 25 associations is reference data, then you don't need to have the entity collection properties at all, you can have one-way associations instead, which are supported in the designer. From the fact that you're loading 25000 of these things, I'm assuming that they're not reference data, but thought I'd mention it just in case. |
|
|
I tried to use the one-way-associations but the I get lots of exceptions:
Therefore this seems to be no solution for us. Furthermore the changes lead to error messages during model saving. As we have a quite complex model I have to rely on these messages to keep the model valid. Regards, Dennis |
|
|
Hi, could you be a bit more precise on how to construct these empty collections:
I quess that I have to do some manual code changes as well as some changes in the editor. Regards, Dennis |
|
|
For the time being you need to edit the code-behind (or change the association Generation to None and implement the members in the partial class). We do not intend this to be a long-term solution, of course, but we need you to evaluate the approach so that we can determine whether it addresses your problem or not; if it does, we'll invest in designer support so you don't need to make manual hacks, but we don't want to invest the effort if it doesn't help you. |
|