View Revisions: Issue #1587

Summary 0001587: NoesisView Garbage Generation Scenario
Revision 2019-11-24 14:49 by stonstad
Description I tracked down the source of a 8 kb per frame garbage allocation to NoesisView.cs. It turns out the cause is something one could argue is developer error, but it is *definitely* a pitfall that should be avoided. These empty try/catches in Update() are dangerous to the extreme for GC allocations and they can be avoided:

        try { if (Input.GetAxis("Noesis_Vertical") > 0.5f) gamepadButtons |= GamepadButtons.Up; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_Vertical") < -0.5f) gamepadButtons |= GamepadButtons.Down; } catch (Exception) {}

        try { if (Input.GetAxis("Noesis_Horizontal") > 0.5f) gamepadButtons |= GamepadButtons.Right; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_Horizontal") < -0.5f) gamepadButtons |= GamepadButtons.Left; } catch (Exception) {}

        try { if (Input.GetButton("Noesis_Accept")) gamepadButtons |= GamepadButtons.Accept; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_Cancel")) gamepadButtons |= GamepadButtons.Cancel; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_Menu")) gamepadButtons |= GamepadButtons.Menu; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_View")) gamepadButtons |= GamepadButtons.View; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_PageLeft")) gamepadButtons |= GamepadButtons.PageLeft; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_PageRight")) gamepadButtons |= GamepadButtons.PageRight; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_PageUp") > 0.5f) gamepadButtons |= GamepadButtons.PageUp; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_PageDown") > 0.5f) gamepadButtons |= GamepadButtons.PageDown; } catch (Exception) {}

        try { float v = Input.GetAxisRaw("Noesis_Scroll"); if (Math.Abs(v) > 0.05f) _uiView.Scroll(v); } catch (Exception) {}
        try { float v = Input.GetAxisRaw("Noesis_HScroll"); if (Math.Abs(v) > 0.05f) _uiView.HScroll(v); } catch (Exception) {}

A developer may choose to remove any one of these input labels for any number of reasons and Noesis will silently allocate multiple KB of garbage for each frame rendered. These thrown exceptions are caught silently. Since Unity does NOT report exceptions while a debugger is attached it is highly likely a developer will never know this is happening. The best case scenario is that they will just think, "Noesis creates garbage," when it usually doesn't.

As a proposed solution, NoesisView could check for the existence of these inputs on Awake() and then disable reading them in Update() if they were not previously defined. This design completely eliminates the need for try/catches in the Update loop and prevents possible GC allocation. This has the added benefit of allowing developers to eliminate Noesis inputs as they may find necessary to accommodate gameplay controls.


Revision 2019-11-24 14:47 by stonstad
Description I tracked down the source of a 9 kb per frame garbage allocation to NoesisView.cs. It turns out the cause is something one could argue is developer error, but it is *definitely* a pitfall that should be avoided. These empty try/catches in Update() are dangerous to the extreme for GC allocations and they can be avoided:

        try { if (Input.GetAxis("Noesis_Vertical") > 0.5f) gamepadButtons |= GamepadButtons.Up; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_Vertical") < -0.5f) gamepadButtons |= GamepadButtons.Down; } catch (Exception) {}

        try { if (Input.GetAxis("Noesis_Horizontal") > 0.5f) gamepadButtons |= GamepadButtons.Right; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_Horizontal") < -0.5f) gamepadButtons |= GamepadButtons.Left; } catch (Exception) {}

        try { if (Input.GetButton("Noesis_Accept")) gamepadButtons |= GamepadButtons.Accept; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_Cancel")) gamepadButtons |= GamepadButtons.Cancel; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_Menu")) gamepadButtons |= GamepadButtons.Menu; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_View")) gamepadButtons |= GamepadButtons.View; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_PageLeft")) gamepadButtons |= GamepadButtons.PageLeft; } catch (Exception) {}
        try { if (Input.GetButton("Noesis_PageRight")) gamepadButtons |= GamepadButtons.PageRight; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_PageUp") > 0.5f) gamepadButtons |= GamepadButtons.PageUp; } catch (Exception) {}
        try { if (Input.GetAxis("Noesis_PageDown") > 0.5f) gamepadButtons |= GamepadButtons.PageDown; } catch (Exception) {}

        try { float v = Input.GetAxisRaw("Noesis_Scroll"); if (Math.Abs(v) > 0.05f) _uiView.Scroll(v); } catch (Exception) {}
        try { float v = Input.GetAxisRaw("Noesis_HScroll"); if (Math.Abs(v) > 0.05f) _uiView.HScroll(v); } catch (Exception) {}

A developer may choose to remove any one of these input labels for any number of reasons and Noesis will silently allocate multiple KB of garbage for each frame rendered. These thrown exceptions are caught silently. Since Unity does NOT report exceptions while a debugger is attached it is highly likely a developer will never know this is happening. The best case scenario is that they will just think, "Noesis creates garbage," when it usually doesn't.

As a proposed solution, NoesisView could check for the existence of these inputs on Awake() and then disable reading them in Update() if they were not previously defined. This design completely eliminates the need for try/catches in the Update loop and prevents possible GC allocation. This has the added benefit of allowing developers to eliminate Noesis inputs as they may find necessary to accommodate gameplay controls.