1. Before updating to Windows 10 you may need to return your Pro license. More information here

Caching AnimationStates for runtime calls is 10 times faster

Discussion in 'Scripting' started by n0mad, Mar 3, 2012.

  1. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Messages:
    3,731
    Hello,

    I only saw this tip in one old topic,and wasn't very sure about how efficient it was, so I ran a test :

    test 1 : assigning to a float variable the weight of an animation by calling it via this[] (ex : anim["walk"]), looping 10000 times


    test 2 : assigning to a float variable the weight of an animation by calling it via an AnimationState cache (ex : AnimationState ac = anim["walk"] before running the test, then calling ac.weight during test), looping 10000 times


    result :

    test 1 returned a duration of 50 to 80 ms per batch of 10000 calls
    test 2 returned a duration of 3 to 8 ms per batch of 10000 calls
    (tested on an i7 920 intel proc)

    Caching which animation clips you're calling is therefore 10 times faster.
    I didn't think it would be this huge a difference, tbh, hence the creation of this topic for further reference.
     
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Messages:
    13,486
    thanks for sharing man, that is very cool.

    Tell me about the game, is she progressing well?
     
  3. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Messages:
    3,731
    Hello Hippo :)
    Yes, the lady has actually finished her diner, and is dressing up to party hard !
    She's putting a lot of attention into drawing those fine eyelines :p
     
  4. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Messages:
    3,731
    I made another interesting test :

    It seems that storing all AnimationStates inside a Dictionary gives twice faster access than with this[animName], too.

    test 1 :

    Code (csharp):
    1. float test;
    2.        
    3.         for (int i = 0; i < 10000; i++)
    4.         foreach(AnimationState ac in _anim)
    5.             test = ac.weight;

    test 2 :

    Code (csharp):
    1.  
    2.         for (int i = 0; i < 10000; i++)
    3.         foreach(KeyValuePair<string, AnimationState> kvp in lib)
    4.             test = kvp.Value.weight;


    There are 510 animation clips inside the Animation sampled component.

    test time with this[clip] : 320 ms
    test time with Dictionary : 151 ms

    The only cullprit is the Dictionary generation time, which was in this case : 231 ms.

    So it seems like using this[animName] is absolutely not recommended at all.

    edit : Additionally, storing the 510 x 2 animations (2 characters) inside the Dictionary didn't create any Memory overhead at all. So I guess that it's really a benefit to store any anim clip, even if it costs 2 seconds more at startup.

    p.s : I measured the base difference between ms values on my PC and on a Galaxy S, and you can expect 10 times the duration of PC test results on the Galaxy S. So I guess 15-20 times on a 3GS, 5 times on a 4S.
     
    Last edited: Mar 3, 2012
  5. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Messages:
    1,082
    Hey n0mad! Might I ask two things of you for complete clarity?

    1.Can you link the original tip-thread you mention? I believe it was Mika's thread(regarding Zombieville) but I'd like to see the one you're referencing.

    2. Can you post pseduo-code for the two original tests you started this thread with?

    Thanks man!

    -Steve
     
  6. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Messages:
    3,731
    Hi Steve :)

    1 - I found this thread last week, so I didn't save the url, sorry :/ But yeah, I recall Mika asking similar questions for Zombieville ^^

    2 - sure :

    test 1 (this[myAnimName]) :

    Code (csharp):
    1. float test;
    2. for (int i = 0; i < 10000; i++)
    3.  test = myCachedAnimationComponent["walk"].weight;
    test 2 (cached AnimationState) :

    Code (csharp):
    1. float test;
    2. AnimationState ac = myCachedAnimationComponent["walk"];
    3. for (int i = 0; i < 10000; i++)
    4.  test = ac.weight;
     
  7. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Messages:
    1,082
  8. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Messages:
    3,731
    Ah yes, precisely :)