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

IsDirty performance hit since 5.4.0 #3307

Closed
trivalik opened this issue May 24, 2023 · 14 comments
Closed

IsDirty performance hit since 5.4.0 #3307

trivalik opened this issue May 24, 2023 · 14 comments

Comments

@trivalik
Copy link

I faced a longer IsDirty run after upgrading.

NHibernate 3.3.1:

image

NHibernate 5.4.2:

image

The first question is, was there a bug in old implementation that now lead to this cascade?
Since the result of IsDirty is true in both cases, I can imagine that there is optimization potential.

The test case of IsDirty is there that we have a table which stores for every element a parent element (not lazy load). The children are as HasMany relation. We remove just near all elements, and this lead to this bad result.

@hazzik
Copy link
Member

hazzik commented May 24, 2023

@trivalik can you share full screenshot for 3.3.1 and also expand all trees for CascadeToOne?

@bahusoid bahusoid changed the title IsDirty performance hint from 3.3.1 to 5.4.2 IsDirty performance hit from 3.3.1 to 5.4.2 May 24, 2023
@trivalik
Copy link
Author

For 3.3.1 is through there was none, it was:

image

For 5.4.2 ( I can imagine that CascadeAfterSafe the problem is like in #1413):
image

@bahusoid
Copy link
Member

You said you have the same performance issue with 5.3. Did you check with 5.2? Can you share how profiling looks for 5.3

@trivalik
Copy link
Author

Wow. I wasn't aware that 5.3.16 has also 7ms.

image

@bahusoid
Copy link
Member

I wasn't aware that 5.3.16 has also 7ms.

Then it's likely #2752 to blame

@trivalik
Copy link
Author

I can confirm that the over 1 second run for IsDirty starts with the changes in commit 89a79d2.

@hazzik

This comment was marked as resolved.

@trivalik

This comment was marked as resolved.

@hazzik
Copy link
Member

hazzik commented May 25, 2023

I ended up the following, but not sure if this is actually the repro

@trivalik, I'm not sure either.

Can you please test if changing this code:

protected virtual void PrepareEntityFlushes(IEventSource session)
{
log.Debug("processing flush-time cascades");
ICollection list = IdentityMap.ConcurrentEntries(session.PersistenceContext.EntityEntries);
//safe from concurrent modification because of how entryList() is implemented on IdentityMap
foreach (DictionaryEntry me in list)
{
EntityEntry entry = (EntityEntry) me.Value;
Status status = entry.Status;
if (status == Status.Loaded || status == Status.Saving || status == Status.ReadOnly)
{
CascadeOnFlush(session, entry.Persister, me.Key, Anything);
}
}
}

And moving Anything out of the foreach loop fixes anything? Like this:

protected virtual void PrepareEntityFlushes(IEventSource session)
{
	log.Debug("processing flush-time cascades");

	ICollection list = IdentityMap.ConcurrentEntries(session.PersistenceContext.EntityEntries);
	var context = Anything; // <<<< HERE
	//safe from concurrent modification because of how entryList() is implemented on IdentityMap
	foreach (DictionaryEntry me in list)
	{
		EntityEntry entry = (EntityEntry) me.Value;
		Status status = entry.Status;
		if (status == Status.Loaded || status == Status.Saving || status == Status.ReadOnly)
		{
			CascadeOnFlush(session, entry.Persister, me.Key, context /* <<<< HERE */);
		}
	}
}

@hazzik

This comment was marked as outdated.

@hazzik hazzik added this to the 5.4.3 milestone May 25, 2023
@hazzik hazzik changed the title IsDirty performance hit from 3.3.1 to 5.4.2 IsDirty performance hit from 5.3.16 to 5.4.2 May 25, 2023
@trivalik
Copy link
Author

Moving out the Anything, out of the foreach loop lead to no SaveOrUpdate call. And solved it for my private test case and for the test case I change in NHibernate.

@hazzik
Copy link
Member

hazzik commented May 25, 2023

@trivalik great. Can you submit a PR?

@hazzik
Copy link
Member

hazzik commented May 25, 2023

loop lead to no SaveOrUpdate call.

I cannot get the SaveOrUpdate call with your code.

@trivalik
Copy link
Author

You are right the unit test does not create a call of FireSaveOrUpdate. But I verified now with 5.4.x branch (before only with the old commit when error comes in), that the calls for CascadeOn is increased. Do not look on the ms because this profiling was to calculate the exact call count, not the times.

Here for the 5.4.x branch:

image

Here with the Anything fix:

image

@hazzik hazzik added the r: Fixed label Jun 6, 2023
@hazzik hazzik closed this as completed Jun 6, 2023
@fredericDelaporte fredericDelaporte changed the title IsDirty performance hit from 5.3.16 to 5.4.2 IsDirty performance hit since 5.4.0 Jul 2, 2023
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