5 ms·
OPs implementation requires 2 comparisons. I think this C expression is clearer, and will sometimes use 1 comparison: num < min ? min : num > max ? max
by geophile 6y ago
OPs implementation requires 2 comparisons. I think this C expression is clearer, and will sometimes use 1 comparison:
num < min ? min :
num > max ? max :
num
- deleted 6y ago[deleted]
- xondono 6y agoTo me the danger of this kind of one liners is that if you use it 2 times somewhere, someone, at some point, will do the lazy refactor of “let’s put it into a function”. int clamp (int value, int min, int max) And that one liner inside. And now you have a double evaluation bomb waiting to go out on your codebase.
- geophile 6y agoWhy? You wrote a function, not a macro.
- xondono 6y agoAccidentally overwrote the middle step: Junior developer puts the one liner on google, finds the typical macro definition and does the change.
- adrianmonk 6y agoMaybe they mean that you might have been unintentionally relying on double evaluation, and then you take it away, and something breaks. Because it worked for the wrong reasons.
- edflsafoiewq 6y agoIncidentally, gcc and clang both compile this to two cmovs for me.
- geophile 6y agoI don't speak x86. Do you mean that these compilers are evaluating both conditions, all the time? At what optimization level?
- edflsafoiewq 6y agoYes, you can check on godbolt. At -O{1,2,3}. At -Os, clang still generates cmovs, but gcc generates a jump.
- benchaney 6y agox86 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
- jacobolus 6y agoBranching is the expensive part, not comparisons.
- cogman10 6y agoThis is 3 branches. The Math method ends up with 4. This is one of those cases where I think it is much more readable to just write the code than to puzzle over what Math.min(Math.max(min, num), max); might be doing. if (num < min) return min; if (num > max) return max; return num; That's how I'd write it. May not be super terse, but anyone that stumbles on this will know precisely what's happening without needing to take a few seconds to puzzle things out.
- jacobolus 6y agoWhat you want is something that compiles to conditional moves. A good compiler should compile your proposed version to the same machine code as the max & min method. If for one reason or another it compiles to branches, it’ll end up being slower. In Javascript in my browser (Safari) when these methods get called enough to get compiled using the most aggressive stage of the JIT, they end up essentially the same speed. On my laptop either one runs about 145 million times per second on one CPU core. I wouldn’t be surprised if a C compiler ended up making this function significantly faster, but I haven’t tested it.