Author Topic: Performance Suggestion  (Read 7343 times)

retn

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 1
  • Posts: 9
    • View Profile
Performance Suggestion
« on: July 20, 2014, 12:45:52 AM »
Hey,

i looked in the source code of ngui and i would like to suggest some performance boosts.

1. Own Hirachy. Dont use Unitys GameObject Tree and GetComponent.
Even AbsoluteBounds is easy calculated with non recursive methods. Relative Coordinates should be calculated within ONE Update Method.
Dont use Broadcast or method invokecation from Unity. Its reflection based and its really slow.

I noticed one of the expensive methods is "CalculateRelativeWidgetBounds". The GetComponent calls are incredible expensive and in scrollviews and other ui stuff
its called very very often. Alot other methods are using GetComponent.

  1. class NGUIComponent {
  2.     private NGUIComponent root;
  3.     private NGUIComponent parent;
  4.    
  5.     public Rect GetAbsoluteBounds() {
  6.             Rect absoluteBounds = bounds;
  7.             NGUIComponent nextParent = parent;
  8.             while (nextParent != null) {
  9.                 absoluteBounds.x += nextParent.Bounds.x;
  10.                 absoluteBounds.y += nextParent.Bounds.y;
  11.                 nextParent = nextParent.Parent;
  12.             }
  13.             return absoluteBounds;
  14.         }
  15. }
  16.  

2. Statics
Remove any static of this project, especially the "current" one. Statics and MonoBehaviours are a mess for the garbage collector.

3. Delegates
A very good base. Your delegates working fine but it has to be in the object space. A Static class with passing lists by reference can not be a good way and
costs a lot.

4. Tweens
Get in Touch with ITween.


Greetz retn




Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Performance Suggestion
« Reply #1 on: July 20, 2014, 09:12:27 AM »
1. This would be quite an undertaking, I think. I do like the idea of it, but if you do a parallel hierarchy, then you either have to ensure synchronization with Unity's hierarchy or remove that entirely. Removing it entirely, will remove the whole visualization of the hierarchy that exists today, the drag drop functionality in the editor and the use of prefabs. Essentially, you'd sorta have to build a second unity within unity to support all the functionality we have now.

There might be options to minimize the GetComponent calls instead.

2. Do you have any sources for this? Static members and methods have their place as long as you use them right. Removing them will require you to make more GetComponents and fetches to handle what any given static does.

3. If I understand right, the EventDelegate is built the way it is to be able to expose it in the editor, but I'm not entirely sure. The syntax for eventdelegate is a little funky for sure. You can always consider using UIEventListener instead, but they don't cover exactly the same bases, I believe.

4. iTween:
"iTween is a free, open-source project. As such, it doesn't require any purchase or licensing to be used on commercial projects or otherwise. " - http://itween.pixelplacement.com/index.php

Yeah, that sounds doable.

retn

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 1
  • Posts: 9
    • View Profile
Re: Performance Suggestion
« Reply #2 on: July 21, 2014, 03:01:27 AM »
1. Well. There are several ways to archieve this.

1.1 The best thing would be to use Unity as a graphicial interface and a code generator exports the designed user interface.
Well. I like Windows Forms. I would kill for such a user interface in Unity.

1.2 In the current version i would suggest something like the following. The parent and root are just assigned in the Start method. On Instantiate it will be assigned automatically and on Parenting you can assign it by code.

  1. public class NGUIComponent : MonoBehaviour {
  2.  
  3.         private NGUIComponent root;
  4.         private NGUIComponent parent;
  5.  
  6.         // Use this for initialization
  7.         void Start () {
  8.                 parent = Find(transform.parent);
  9.                 root = Find (transform.root);
  10.                 Debug.Log (string.Format ("[NGUIComponent, Source: {0}, Parent: {1}, Root: {2}] ", transform, parent, root));
  11.         }
  12.  
  13.         private NGUIComponent Find (Transform source) {
  14.                 if (null == source) {
  15.                         return null;
  16.                 }
  17.                 return source.GetComponent<NGUIComponent> ();
  18.         }
  19.  
  20.         public void OnDestroy () {
  21.                 parent = null;
  22.                 root = null;
  23.         }
  24. }
  25.  

The NGUIComponent contains the calculated Bounds as well. I would say to ensure theres no much invocation, i suggest to process any NGUIComponent in one Update method.
Any component is registered to this NGUIManager itsself and is processed in one Update. Even the Tweens, moves  etc. Anything else should be handled by delegates or interfaces.

  1. public class GuiManager {
  2.  
  3.         public void Update () {
  4.                 NGUIManager.Instance.Update();
  5.         }
  6. }
  7.  

This approach is like the Java Component Model. Component is anything. Panel is a collection of components. Windows is a collection of panels.

But well. I cant ensure anything for this. I just know theres no need to call GetComponent so often. It really kills this great framework.


2. The Statics?
I found the following code in nearly any NGUI file. I replaced it with <T> to visualize that any class has it. Because of the massive code duplication, i think its a surrounding for something.
Well statics are not bad. Yesssssch. :)

  1. static public T current;
  2.  
  3. current = this;
  4. .
  5. .
  6. .
  7. current = null;
  8.  

3. Well. I think theres no need for a static class like EventDelegate. In most cases statics are a lazy way to solve problems. Separate Events for each NGUI Tool would be an approvement as well.

Unity and UI is since version 1.0 a mess and i have respect for any improvement and ui developing. This framework is really an improvement but it has edges need to be rounded. :)


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Performance Suggestion
« Reply #3 on: July 21, 2014, 05:17:27 PM »
1. The chances of this happening at this stage in NGUI are slim to none. NGUI uses Unity's hierarchy for simplicity and visualization, as it had for nearly 3 years now. Yes, I would like it to have its own hierarchy as it would make a lot of things easier, but then visualization would be broken, as Nicki pointed out. It will also not be possible to attach scripts directly to specific game objects. For example, attaching a MonoBehaviour to drive an animation of a slider's thumb.

2. Nicki was asking where you're getting the info from why statics are bad for GC. I've never heard of anything like that either, and it makes no sense from software's point of view. Why would the affect GC? All NGUI does is sets a reference, then clears it. There are no 'new' being created, thus no GC to collect. Same for the MonoBehaviours. Mess for GC? GC only kicks in if you create and destroy things. The MonoBehaviours are there, they get neither created nor destroyed, therefore GC is not affected.

NGUI strives for zero GC allocation, and while not always possible, it is indeed the case most of the time. Even draw buffers are re-used, and even if you change something in your UI (such as color of a widget), draw buffers don't get re-allocated -- the same arrays are simply re-used.

retn

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 1
  • Posts: 9
    • View Profile
Re: Performance Suggestion
« Reply #4 on: July 21, 2014, 07:06:06 PM »
The statics.... here we go.

Unity is running the Mono Runtime Enviroment and due to licening of this Enviroment, Unity is always behind the current Mono Version.

Since Unity exists there are bugs in the Garbage Collector of Mono, not Unity! Static cant be cleared automatically and big amount of allocated memory making trouble. I had big projects and it was really a headbang till we found a solution. So. Since this i just advice guys not to use statics, especially in MonoBehaviours, which have no constructor and destructor. Dont point me to Start and Destroy, thats still something else.



For example in NGUI. The Scrollview.

If you have a simple scrollview with 100 entries. Adding and Removing costs alot of memory. Moving the entries is not possible on mobile devices. So thats why i searched for reasons in NGUI. And i found statics and huge calls of Unity methods. My balls alerted me, thats something wrong.

So. Well. Ive built my own Scrollview by altering the entries and not adding, removing or moving them. So i can scroll endless entries without having a performance loss.

If NGUI wants to be significant the best ui system, go for a new hierachy and get rid of GetComponent and Unitys method invocation. :)

Hope that brought light into the tunnel :D.


PS: Use "Visual C# + Resharper Plugin" and it will tell you alot about the code quality. And again. I dont attack NGUI. Its still good work but it really needs a refactoring. Simple solutions are indeed the best, if they have a good result.

« Last Edit: July 21, 2014, 07:36:47 PM by retn »

Eskema

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 12
    • View Profile
Re: Performance Suggestion
« Reply #5 on: July 23, 2014, 12:54:21 AM »
Hey,

i looked in the source code of ngui and i would like to suggest some performance boosts.

4. Tweens
Get in Touch with ITween.


Greetz retn

itween??, are you talking about performance and itween?, god help us all......

If you really want a decent tween system, use hotween or gokit, but itween......

retn

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 1
  • Posts: 9
    • View Profile
Re: Performance Suggestion
« Reply #6 on: July 23, 2014, 05:55:22 AM »
itween??, are you talking about performance and itween?, god help us all......

If you really want a decent tween system, use hotween or gokit, but itween......

Hey. Thanks for sharing this. I tried it immediatly and it looks quite nice.

GoKit uses actions as callbacks, fluent interfaces and a good code structure.
Hotween uses delegates and has also a good code structure.

Indeed well better coded than itween. :)

I think i go for GoKit first :D
 
What are your experience with GoKit and Hotween?

Eskema

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 12
    • View Profile
Re: Performance Suggestion
« Reply #7 on: July 23, 2014, 06:16:41 AM »
Hey. Thanks for sharing this. I tried it immediatly and it looks quite nice.

GoKit uses actions as callbacks, fluent interfaces and a good code structure.
Hotween uses delegates and has also a good code structure.

Indeed well better coded than itween. :)

I think i go for GoKit first :D
 
What are your experience with GoKit and Hotween?

The main issue about itween is not the code, is the garbage collector, itween it's completely outdated and a monster in terms of performance.

Both options get the job done, I have 2 games, in one of them I use gokit and hotween in the other, no differences at all, it's just a matter of what api seems more usable for you, both have a perfect performance in terms of garbage collection :)