Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions Tips to optimize your expressions – Which expression to avoid?

  • Tips to optimize your expressions – Which expression to avoid?

  • Remi Monedi

    April 7, 2020 at 9:45 am

    Hi everyone,

    I’m using more and more expressions in my AE projects and sometimes expressions make them quite slow (duplicating a layer with a lot of expressions takes a while , or preview/render a composition). From time to time in posts on this forum you can read about some expressions being “slow”.
    I wonder if you know some of them and if you have some tips or workarounds!

    Few tips I already know :

    – Avoid Math. functions (but is there a workaround? for instance for Math.round()?)
    – Prefer keyframes to expression (use “Convert Expression to Keyframe”)
    Scripts are faster than expression.

    Have a nice day!

  • Andrei Popa

    April 7, 2020 at 12:11 pm

    Scripts are not faster than expression at execution.
    But an expression executes at each frame.
    The script only executes one time, when you ask it to.
    An expression equal in code with a script is like running that script for each frame.

    I didn’t know Math is slow.

    I know that it is very slow to link another property that links to another property and so on(recursively).
    Ex: if you put some layers one under the other, with some expression like thisComp.layer(index-1).position+[0,20], each time you add another layer, things complicate in an exponential manner. Because each layer calculates all the previous layers, since expressions don’t save the value. I don’t know if they optimized this in the latest versions(19-20), but this was a pain before.

    There are also the ones that calculate multiple values you had before in the composition, using valueAtTime() in some loops. The longer the composition, the more it takes for each frame to render.

    Turning to keyframes is a bit similar to scripts. When using “Convert Expression to Keyframes” you calculate the expressions, and then save the results. No more calculation when rendering.

    If anyone has more information, like what is super slow, of how can you measure the speed of your expressions, I would also love to hear.

    My Envato portfolio.

  • Darby Edelen

    April 7, 2020 at 6:16 pm

    I wouldn’t avoid Math expressions. I can’t think of a more efficient way of using trig functions.

    Any loop is going to add a significant amount of calculation, so try to avoid them if possible.

    Try to use conditionals to skip expensive (e.g. loops) code when unnecessary. If your expression should only evaluate within 1 second of a layer marker then find out if you’re within 1 second of a layer marker first and skip the expensive code if you’re not.

    Darby Edelen

  • Remi Monedi

    April 8, 2020 at 12:33 pm

    Thank you Andrei and Darby for the clarifications! About the Math functions I don’t recall when I read it but it was on this forum for sure. A way to calculate the speed of expressions would be great for sure since the time difference between two methods is often noticeable only with biiig amount of expressions.

    For instance, to get the speed of a layer (based on its position), these 3 methods gave the same results (almost) but which one is the fastest do you think?

    // METHOD 1
    speed = thisLayer.transform.position.velocityAtTime(time);

    // METHOD2
    L =thisLayer;
    p1 = L.transform.position.valueAtTime(time);
    p0 = L.transform.position.valueAtTime(time-0.01);
    speed = (p1 - p0)*100;

    // METHOD 3
    L =thisLayer;
    p1 = L.toWorld (L.anchorPoint,time+thisComp.frameDuration/2);
    p0 = L.toWorld (L.anchorPoint,time-thisComp.frameDuration/2);
    speed = (p1 - p0)/thisComp.frameDuration;

  • Darby Edelen

    April 8, 2020 at 8:54 pm

    The expressions you’re using as examples are functionally different. Method 1 is most likely the fastest as I would assume it hooks into some lower level function.

    Method 2 is using an arbitrary time offset to determine the change in position and is probably less accurate than method 1.

    Method 3 is the only one that will return velocity in world space, so even if the layer position is not animated but instead moved by a parent you’ll get a meaningful result. Method 3 is also probably less accurate than method 1 in terms of the result.

    I think it’s also important to note that all of these methods return a velocity and not a speed. Velocity is a vector value while speed is the magnitude of the velocity vector.

    Darby Edelen

  • Remi Monedi

    April 9, 2020 at 7:33 am

    We know AE updates the result of an expression at each frame of the composition and sometimes we don’t need this constant updating, it can affect the preview/render time.
    I found 2 ways of limiting an expression’s execution to exactly once :

    METHOD 1
    By adding the comment : // cacheCompareSamplesPerSecond 0
    It works since AE CC2014, but it seems it’s a bit tricky to use : “Anything complex or potenially dynamic, and the line would disable itself it seemed.”

    METHOD 2
    Add this expression : posterizeTime(0);
    Works since AE 2020, a different use for the classic posterizeTime function.

    I was not able to make the 1st method work with my project and for the 2nd, I just made a quick test and it’s working.
    Did you ever used one of these methods? Do you have any thoughts on this?

    // METHOD 1
    // cacheCompareSamplesPerSecond 0

    // METHOD 2

  • Remi Monedi

    April 10, 2020 at 12:39 pm

    With the help of an AE project file allowing me to apply different expressions to 240 layers easily (for a 10s comp), I have some conclusions about the VELOCITY expressions mentioned previously and their influence in render time :
    (note : the conclusions are for information only, with more complex projects, I’m sure there are other things to take into account but it’s a start!)

    For expressions giving the position velocity at present time (time), I tried 3 different methods giving the almost same results (more or less 1 pixel) :

    speed = thisLayer.transform.position.velocityAtTime(time);

    METHOD 2
    L =thisLayer;
    p1 = L.transform.position.valueAtTime(time+.01);
    p0 = L.transform.position.valueAtTime(time-.01);
    speed = (p1 – p0)*50;

    L =thisLayer;
    p1 = L.toWorld (L.position,time+.01);
    p0 = L.toWorld (L.position,time-.01);
    speed = (p1 – p0)*100;

    Well, no big surprise I’d say, Darby called it previously.
    BUT there is an interesting change if you’re looking to calculate the velocity at time-.01 :

    L =thisLayer;
    p1 = L.transform.position.valueAtTime(time);
    p0 = L.transform.position.valueAtTime(time-0.01);
    speed = (p1 – p0)*100;

    METHOD 1
    speed = thisLayer.transform.position.velocityAtTime(time-.01);

    L =thisLayer;
    p1 = L.toWorld (L.position,time);
    p0 = L.toWorld (L.position,time-.01);
    speed = (p1 – p0)*100;

    In both cases, between the “velocityAtTime” and “valueAtTime” based expressiosn there is not a huge difference in render time but on my machine it was still a few seconds for just a 10s comp!
    Not sure if anyone will be interested in these observations. I’m still interested in other tips on expression!

  • Joe Richardson

    April 17, 2020 at 7:38 am

    I guess try to avoid RegEx. I’ve been using it in the expression selector, and it causes a significant delay. I guess it helps to optimize it using “?:” to avoid unnecessary capture groups. Also, Expression-Selector Expressions don’t render in Adobe Media Encoder!

    The other one was Math.apply to get the max/min of an array. It sped up significantly in the new JS engine, but I notice it slows down in the rendering.

Viewing 1 - 8 of 8 posts

Log in to reply.

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy