Ternary vs Built-in function: Looking for the more efficient operator

I’m doing parallax scrolling animations and register and event listener for the scroll event. This means the function is called at a very high rate. So, I’m looking for the right choice to save a little computing effort.

Does anyone know if there is a difference between these two functions to get a clamped return value?

function clamp(num, min, max) {
  return num <= min ? min : num >= max ? max : num;
}

function clamp(num, min, max) {
  return Math.min(Math.max(num, min), max);
}

My gut says the second one would be faster since built in functions are usually optimized either in layout or in the way the code gets interpreted. I wasn’t sure though so I threw together a quick test. Here is the test code that I ran in node (I am assuming that your using javascript but I could be wrong).

function clamp1(num, min, max) {
  return num <= min ? min : num >= max ? max : num;
}

function clamp2(num, min, max) {
  return Math.min(Math.max(num, min), max);
}

const min = 4;
const max = 5;


console.time('test1');
for (let i = 0; i < 100000; i++) {
  const num = Math.floor(Math.random() * 10);
  clamp1(num, min, max);
}
console.timeEnd('test1');

console.time('test2');
for (let i = 0; i < 100000; i++) {
  const num = Math.floor(Math.random() * 10);
  clamp2(num, min, max);
}
console.timeEnd('test2');

These are the results of running it six times, 3 with test2 first and 3 with test1 first.

test2: 0.162ms
test1: 0.083ms

test2: 3.506ms
test1: 3.076ms

test2: 3.621ms
test1: 3.19ms

test1: 4.178ms
test2: 2.549ms

test1: 3.894ms
test2: 2.397ms

test1: 3.655ms
test2: 2.619ms

test1: 3.812ms
test2: 2.658ms

It seems like the second one is faster since the difference is greater when it is run second. Also alot of interpreters and compilers are really freaking smart and can optimize on the fly or during compile so it might not even make much difference in the long run. You can probably choose either one and get adequate results. I would say try whichever one is easier for you to understand when reading it and if it has a crazy performance penalty you can change it. Hope this helps.

2 Likes

Thanks for the detailed answer! (I did not expect this result.)

Yes, I corrected the category of my question.

It doesn’t really matter since I’m calling the clamp function – but I find the second one easier to read. Since this is also the winner of the race, I’ll go with that.
Do you have an idea why the execution order matters?

Which is a good reason, and it is strictly functional with minimum logic and the use of HOF. It is also the pattern implemented in the lodash object.

1 Like

I don’t know exactly but if I had to guess I would say it has something to do with caching or gradual optimization (since JavaScript uses JIT see article below). After running some more tests to satisfy my own curiosity i found that increasing the number of loops makes the second option start out performing no matter what order it was run in (increased to like 100000000 or something).

1 Like

Thanks for the research and the article. So it is by no means a matter of BigO notation only, there is a lot more to consider. Since I am currently facing performance issues with my parallax scrolling page, I guess I have to refactor it so it uses canvas and requestAnimationFrame.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.