Caching AnimationStates for runtime calls is 10 times faster

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

  1. n0mad

    n0mad

    Member

    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:
    10,437
    thanks for sharing man, that is very cool.

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

    n0mad

    Member

    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

    Member

    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

    Member

    Joined:
    Jan 17, 2009
    Messages:
    917
    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

    Member

    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

    Member

    Joined:
    Jan 17, 2009
    Messages:
    917
  8. n0mad

    n0mad

    Member

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