Open Turnerj opened 1 year ago
There are further improvements possible based on the scenario in #362 as a big problem with the implementation when setting multiple entities is that the number of checks via GetEntry
grows with every extra entity.
That is to say, you add 10 items to an empty entity container:
We can avoid a bunch of checks by not checking the items we're adding against themselves while we're adding them. So if someone were to add 500,000 items, we don't actually need to check them against each other.
That said, without doing the checks, it does mean it is possible for someone to intentionally double up the exact same reference entity in the database (eg. the enumerable has the same entity twice). This could be avoided by chucking the whole thing in a HashSet
perhaps but that will cause a large amount of allocations, especially for the case with 500,000 entities being added.
I would like to work out a good/better solution for adding many entries at once without a large number of allocations while addressing the underlying performance problem before merging this fix.
Fixes #362
When adding a very large number of entities to the change tracker, it was performing an extreme number of calls to
GetValue
on thePropertyInfo
. This isn't typically slow but is very slow when call as often as it was.This PR contains two primary changes to improve the performance of the existing code
GetEntry
lookups to avoid callingGetIdValue
unnecessarilyGetIdValue
Up to 98% faster for setting the entity state.
Before
After