I've profiled my long-running-integration-test.
Scenario (with my partial data set):
- importing data from an XML file
- ~13000 entities each with ~5 embedded collections
- Entities are flushed once, after all entities are created and relations are set up
With an earlier NH version (3.1 I think) import took ~2 minutes. Now (3.2 trunk) it takes 18 minutes. Most of the time (15 minutes) is spent in ActionQueue class, method SortInsertActions.
The question is: apart of my own code and domain, is that OK?
I've found a temporarily acceptable workaround, I'm flushing entities in batches of 1000, it allows me to import all my data in a reasonable time.
Call stack starting with Flush(), NH 3.1 from nuget:
100.00 % Flush • 54'769 ms • NHibernate.Impl.SessionImpl.Flush
100.00 % OnFlush • 54'769 ms • NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent)
96.69 % PerformExecutions • 52'956 ms • NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource)
96.69 % ExecuteActions • 52'956 ms • NHibernate.Engine.ActionQueue.ExecuteActions
96.69 % ExecuteActions • 52'956 ms • NHibernate.Engine.ActionQueue.ExecuteActions(IList)
96.69 % Execute • 52'956 ms • NHibernate.Engine.ActionQueue.Execute(IExecutable)
75.79 % Execute • 41'510 ms • NHibernate.Action.EntityInsertAction.Execute
►39.01 % PostInsert • 21'363 ms • NHibernate.Action.EntityInsertAction.PostInsert
►22.87 % Insert • 12'524 ms • NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object, Object[], Object, ISessionImplementor)
Call stack starting with Flush(), NH 3.2 trunk:
100.00 % Flush • 1'053'864 ms • NHibernate.Impl.SessionImpl.Flush
100.00 % OnFlush • 1'053'864 ms • NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent)
88.59 % FlushEverythingToExecutions • 933'652 ms • NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent)
88.48 % FlushEntities • 932'457 ms • NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent)
88.37 % SortActions • 931'295 ms • NHibernate.Engine.ActionQueue.SortActions
88.37 % SortInsertActions • 931'295 ms • NHibernate.Engine.ActionQueue.SortInsertActions
12.79 % get_Instance • 134'801 ms • NHibernate.Action.EntityAction.get_Instance
6.41 % get_Item • 67'535 ms • System.Collections.Generic.List`1.get_Item(Int32)
1.03 % get_Count • 10'842 ms • System.Collections.Generic.List`1.get_Count
0.12 % get_Item • 1'241 ms • System.Collections.Generic.Dictionary`2.get_Item(TKey)
0.01 % Contains • 55 ms • System.Collections.Generic.List`1.Contains(T)
►0.11 % OnFlushEntity • 1'163 ms • NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent)
►0.10 % PrepareEntityFlushes • 1'024 ms • NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource)
►0.01 % FlushCollections • 113 ms • NHibernate.Event.Default.AbstractFlushingEventListener.FlushCollections(IEventSource)
►0.01 % PrepareCollectionFlushes • 58 ms • NHibernate.Event.Default.AbstractFlushingEventListener.PrepareCollectionFlushes(ISessionImplementor)
11.40 % PerformExecutions • 120'108 ms • NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource)
11.40 % ExecuteActions • 120'108 ms • NHibernate.Engine.ActionQueue.ExecuteActions
11.40 % ExecuteActions • 120'108 ms • NHibernate.Engine.ActionQueue.ExecuteActions(IList)
11.38 % Execute • 119'885 ms • NHibernate.Engine.ActionQueue.Execute(IExecutable)
►10.01 % Execute • 105'503 ms • NHibernate.Action.EntityInsertAction.Execute
►1.33 % Execute • 13'989 ms • NHibernate.Action.CollectionRecreateAction.Execute
►0.04 % RegisterCleanupActions • 392 ms • NHibernate.Engine.ActionQueue.RegisterCleanupActions(IExecutable)
►0.01 % PostFlush • 104 ms • NHibernate.Event.Default.AbstractFlushingEventListener.PostFlush(ISessionImplementor)
Valeriu