Live data from Hacker News

Math.min(Math.max(num, min), max)

twitter.com

201–210 of 291 posts

Re: Math.min(Math.max(num, min), max)

#201
I always used to get confused by the function names “min” and “max” because they return the minimum and maximum, but typically when you use them you are thinking in terms of applying a minimum or maximum bound. Having a dedicated clamp function significantly helps although imo there is not a single correct order for the parameters to go in.

Re: Math.min(Math.max(num, min), max)

#202
post #127
post #79

Earlier quoted context omitted.

Are you saying a C++ developer shouldn't use the standard library?

Many performance-critical C++ programmers treat std with suspicion. One thing to keep in mind is that the interface is standard, but the implementations are not, and can foil you on cross-platform development. Another is that you might not need everything that a std container provides, and you can get away with a streamlined data structure that doesn't support those unnecessary operations. But as a sibling commenter…

I'd much rather work on an application that utilized the standard lib than one that brought in dependencies and custom data structures.

If it really is a bottleneck on a hot path then go for it. But not using it because of some ancient anecdotes is going to lead to an unmaintainable mess.

Re: Math.min(Math.max(num, min), max)

#203

Earlier quoted context omitted.

Incidentally, gcc and clang both compile this to two cmovs for me.

I don't speak x86. Do you mean that these compilers are evaluating both conditions, all the time? At what optimization level?

Yes, you can check on godbolt. At -O{1,2,3}. At -Os, clang still generates cmovs, but gcc generates a jump.

Re: Math.min(Math.max(num, min), max)

#204
post #75

Earlier quoted context omitted.

Easy to remember, but may take some time to grasp: Arrays.sort( {lower_bound, num, upper_bound} )[1]; Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) (You can’t reduce it to the min/max call because it also works if you accidentally pass a lower bound that’s larger than the upper bound. Worst-case, the above takes 3 comparisons, unless at least two of the inputs are constants)

> Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) I did exactly this for my PhD! https://chrisseaton.com/phd/

I'm glad things like this are being worked on. I have been writing a set of implementations of the nBody benchmark in JavaScript using various forms of abstractions. In an ideal world they should all take the same speed since they perform the same fundamental task and produce the same result. They just represent different scales of optimization effort.

It's interesting seeing the difference between vectors in arrays vs objects and if you do immutable versions. The trickiest to optimize form is using a micro vector library which uses closures and array map().

    var vop = op => ((a, b) => (a.map((v, i) => op(v, b[i]))));
    var vdiff = vop((a, b) => a - b);
    var vequals = (a, b) => {  return (vdiff(a, b).reduce((c, d) => c + Math.abs(d), 0)) === 0;};
    var vadd = vop((a, b) => a + b);
    var vdot = (a, b) => a.reduce((ac, av, i) => ac += av * b[i], 0);
    var vlength = a => Math.sqrt(vdot(a, a));
    var vscale = (a, b) => a.map(v => v * b);
    var vdistance = (a, b) => vlength(vdiff(a, b));
Currently on my lowly atom laptop and FireFox. The version using mutable objects is ten times faster than the mapping immutable array version. I live in hope that one day there will be an optimizer that turns

    var transpose = matrix => (matrix.reduce(($, row) => row.map((_, i) => [...($[i] || []), row[i]]), []));
    var multiply = (a, b, ...rest) => (!b) ? a : multiply(a.map((p => transpose(b).map(q => vdot(p, q)))), ...rest);
Into a CPU optimum (or dare I suggest GPU) version of a matrix multiply.

Re: Math.min(Math.max(num, min), max)

#205
post #201

I always used to get confused by the function names “min” and “max” because they return the minimum and maximum, but typically when you use them you are thinking in terms of applying a minimum or maximum bound. Having a dedicated clamp function significantly helps although imo there is not a single correct order for the parameters to go in.

More often than not no.. I am trying to find the min/max value in a set. Bit a bound

Re: Math.min(Math.max(num, min), max)

#207
post #75

Earlier quoted context omitted.

Easy to remember, but may take some time to grasp: Arrays.sort( {lower_bound, num, upper_bound} )[1]; Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) (You can’t reduce it to the min/max call because it also works if you accidentally pass a lower bound that’s larger than the upper bound. Worst-case, the above takes 3 comparisons, unless at least two of the inputs are constants)

> Next challenge: teach the optimizer to make that almost as fast as the min/max way ;-) I did exactly this for my PhD! https://chrisseaton.com/phd/

[deleted]

Re: Math.min(Math.max(num, min), max)

#208

Earlier quoted context omitted.

Incidentally, gcc and clang both compile this to two cmovs for me.

I don't speak x86. Do you mean that these compilers are evaluating both conditions, all the time? At what optimization level?

x86 has instructions that execute conditionally. Most conditionals in higher level languages get compiled to conditional jumps, but using conditional operations this isn't necessary. The same code path is taken in all cases, and the instructions effect is what is conditional.

In the case of cmov, it is either a nop or a mov dependent on the state of the conditional flags. Using this construct instead of a regular mov guarded by conditional jumps has better performance in some cases.

On my machine gcc is outputting a combination of conditional jumps and conditional movs at all optimization levels

Re: Math.min(Math.max(num, min), max)

#210

Earlier quoted context omitted.

> in desktop edition of the runtime huh?

MS .NET framework. Unfortunately, for the last couple years it lags behind .NET core. Even 2 years old .NET core 2.1 is better in some regards than the latest desktop version 4.8.

.NET 5 will be based on .NET Core. It's already in preview.
Post reply on HN