Undo operation takes 20 minutes with a prefab, but instantaneous without?

Hello all,

We have a fairy large scene that is broken up into 6 top-level prefabs for each major area of the world. The reason for this workflow is to avoid merge conflicts in source control – Developers edit generally one prefab at a time rather than the master scene file.

The number of objects in the top-level prefab is on the order of thousands, but is by no means obscene: The game runs quite smoothly with everything loaded.

However, there are certain workflows in the editor that are completely unusable, and through my testing I can only conclude is somehow related to the usage of prefabs, possibly nested prefabs.

The most egregious example is making a very simple change to an object in the prefab, such as changing scale, and then undoing it. The undo operation takes on average about 20 minutes to complete.

I actually profiled this using UIForETW and can see that there are tens of thousands of “InsertPropertyModificationInternal” calls happening:

If, on the other hand, i select the top-level prefab and “Unpack”, then the undo operation completes instantaneously.

Any ideas what could possibly be going on here? I’m not even saving the scene or prefab yet – how could undoing the scale change of a single object in a large prefab cause so much unnecessary work to be done?

Bump – Anyone have any ideas of where to investigate furhter? The slowdown unfortunately makes prefabs completely unusable for us.

I was also able to capture a stalls.log trace using the latest version of unity and enabling the editor stall diagnostic logging, which shows the same function delay:

===== STALL BEGIN at 2549.83
WinMain;MainMessageLoop;DispatchMessageW;CallWindowProcW;GUIView::GUIViewWndProc;GUIView::ProcessEventMessages;CallGlobalInputEvent;Scripting::UnityEditor::EditorApplicationProxy::Internal_CallGlobalEventHandler;ScriptingInvocation::Invoke<void>;ScriptingInvocation::Invoke;scripting_method_invoke;mono_runtime_invoke;do_runtime_invoke;mono_jit_runtime_invoke;(wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr);UnityEditor.EditorApplication:Internal_CallGlobalEventHandler ();UnityEditor.ShortcutManagement.ShortcutIntegration:EventHandler ();UnityEditor.ShortcutManagement.ShortcutController:HandleKeyEvent (UnityEngine.Event);UnityEditor.ShortcutManagement.Trigger:HandleKeyEvent (UnityEngine.Event,UnityEditor.ShortcutManagement.IContextManager);UnityEditor.ShortcutManagement.MenuItemEntryDiscoveryInfo:<.ctor>b__7_0 (UnityEditor.ShortcutManagement.ShortcutArguments);(wrapper managed-to-native) UnityEditor.EditorApplication:ExecuteMenuItem (string);EditorApplication_CUSTOM_ExecuteMenuItem;MenuController::ExecuteMainMenuItem;MenuController::ExecuteMenuItem;UndoManager::Undo;UndoManager::ApplyUndo;PropertyDiffUndo::Apply;BatchApplyPropertyModification::Complete;SetPropertyModifications;PrefabModification::SetModifications;InsertPropertyModificationInternal 619
WinMain;MainMessageLoop;DispatchMessageW;CallWindowProcW;GUIView::GUIViewWndProc;GUIView::ProcessEventMessages;CallGlobalInputEvent;Scripting::UnityEditor::EditorApplicationProxy::Internal_CallGlobalEventHandler;ScriptingInvocation::Invoke<void>;ScriptingInvocation::Invoke;scripting_method_invoke;mono_runtime_invoke;do_runtime_invoke;mono_jit_runtime_invoke;(wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr);UnityEditor.EditorApplication:Internal_CallGlobalEventHandler ();UnityEditor.ShortcutManagement.ShortcutIntegration:EventHandler ();UnityEditor.ShortcutManagement.ShortcutController:HandleKeyEvent (UnityEngine.Event);UnityEditor.ShortcutManagement.Trigger:HandleKeyEvent (UnityEngine.Event,UnityEditor.ShortcutManagement.IContextManager);UnityEditor.ShortcutManagement.MenuItemEntryDiscoveryInfo:<.ctor>b__7_0 (UnityEditor.ShortcutManagement.ShortcutArguments);(wrapper managed-to-native) UnityEditor.EditorApplication:ExecuteMenuItem (string);EditorApplication_CUSTOM_ExecuteMenuItem;MenuController::ExecuteMainMenuItem;MenuController::ExecuteMenuItem;UndoManager::Undo;UndoManager::ApplyUndo;PropertyDiffUndo::Apply;BatchApplyPropertyModification::Complete;SetPropertyModifications;MergePrefabInstance;MergePrefab;MergePrefabInternal;MergePrefabChanges;InheritGameObjectAndTransformProperties;BuildCorrespondingObjectCache;core::hash_map<int,Instancing::PropertyData * __ptr64,core::hash<int>,std::equal_to<int> >::insert_internal<int const & __ptr64,Instancing::PropertyData * __ptr64 const & __ptr64> 1
WinMain;MainMessageLoop;DispatchMessageW;CallWindowProcW;GUIView::GUIViewWndProc;GUIView::ProcessEventMessages;CallGlobalInputEvent;Scripting::UnityEditor::EditorApplicationProxy::Internal_CallGlobalEventHandler;ScriptingInvocation::Invoke<void>;ScriptingInvocation::Invoke;scripting_method_invoke;mono_runtime_invoke;do_runtime_invoke;mono_jit_runtime_invoke;(wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr);UnityEditor.EditorApplication:Internal_CallGlobalEventHandler ();UnityEditor.ShortcutManagement.ShortcutIntegration:EventHandler ();UnityEditor.ShortcutManagement.ShortcutController:HandleKeyEvent (UnityEngine.Event);UnityEditor.ShortcutManagement.Trigger:HandleKeyEvent (UnityEngine.Event,UnityEditor.ShortcutManagement.IContextManager);UnityEditor.ShortcutManagement.MenuItemEntryDiscoveryInfo:<.ctor>b__7_0 (UnityEditor.ShortcutManagement.ShortcutArguments);(wrapper managed-to-native) UnityEditor.EditorApplication:ExecuteMenuItem (string);EditorApplication_CUSTOM_ExecuteMenuItem;MenuController::ExecuteMainMenuItem;MenuController::ExecuteMenuItem;UndoManager::Undo;UndoManager::ApplyUndo;UndoManager::PostApply;SceneTracker::FlushDirty;RecordPrefabInstancePropertyModificationsAndValidate;GeneratePrefabPropertyDiff;ExtractCurrentValueOfAllModifications 144
===== STALL END after 797.70s

Hi @minism , we’ve starting seeing this exact issue, but “only” stuck for about 1 min. Any more info recently? :frowning:

Should probably try posting in the prefabs forum.

Nested prefabs has some pretty bad performance characteristics that’s gotten improved, but not fixed since they were introduced. Somebody at Unity would probably love to look at your project to see what the problem is.

I was working with this issue a while back, turns out that there was an issue with serializing a byte array on the prefab. Our scene data was 1.3 million lines instead of the expected 40 000. If I recall correctly it serialized each byte as an individual array. It was solved when I used a serialized string as a go-between (by calling Convert.ToBase64String()).

If you’re still having this issue, I would check your scene files to see if there are any abnormalities.