Are Ternary Operations optimized at compile time?

Looking for smart ways to do a simple value clamp without much if/else branching, I came upon a StackOverflow thread where the same question was asked, but for C.

What surprised me in that thread was mention of ternary operations being more compiler friendly than if/else blocks.

Is this so in Java?

I’m asking mostly because I have a liking for ternary operations, but generally just because the code is compact, although I’ve been discouraged from using them in the past (at work, mostly) due to them being harder to read sometimes.

I always assumed that ternary operators where, under the hood, just a compact form of an if/else block (just like switch operations are, as far as I know).

So this code:


public static double clamp(double value, double min, double max)
{
	return value < low? low : value > high? high : value;
}

I though would be equivalent to this:


public static double clamp(double value, double min, double max)
{
	if(value < low) return low;
	if(value > high)return high;
	return value;
}

But now I’m suspecting that assumption is wrong. Am I wrong in my assumption that my assumption is wrong? Or was I right in my previous assumption and thus my current assumption is wrong?

(Yes, on that last line I’m being an asshole) :stuck_out_tongue:

No idea. Have to wait for one of the Java wizards to answer this one.

That being said I’ve never had if/else/ternary blocks being the bottleneck in my programs. I prefer if/else to ternary unless it’s a really trivial thing and I can’t be bothered to write a few extra lines of code.

It compiles to (almost) the same bytecode, so the JIT can’t tell the difference.

btw, switch statements are no simple if else chains. There compiled to lookup tables, because of that you are only allowed to use constants for the cases.

[quote=“Oskuro,post:1,topic:42998”]
Indeed. You can check for yourself with the javap tool. If the class is

public class Test
{
	public static double clamp1(double value, double min, double max)
	{
	   return value < min ? min : value > max ? max : value;
	}

	public static double clamp2(double value, double min, double max)
	{
	   if (value < min) return min;
	   if (value > max)return max;
	   return value;
	}
}

then javap Test gives

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public static double clamp1(double, double, double);
  Code:
   0:	dload_0
   1:	dload_2
   2:	dcmpg
   3:	ifge	10
   6:	dload_2
   7:	goto	23
   10:	dload_0
   11:	dload	4
   13:	dcmpl
   14:	ifle	22
   17:	dload	4
   19:	goto	23
   22:	dload_0
   23:	dreturn

public static double clamp2(double, double, double);
  Code:
   0:	dload_0
   1:	dload_2
   2:	dcmpg
   3:	ifge	8
   6:	dload_2
   7:	dreturn
   8:	dload_0
   9:	dload	4
   11:	dcmpl
   12:	ifle	18
   15:	dload	4
   17:	dreturn
   18:	dload_0
   19:	dreturn

}

As you can see, both of them are conditions, gotos, and returns. The difference is that clamp1 uses a slot on the stack to hold the value until its single dreturn, whereas clamp2 turns every return statement into a dreturn bytecode. As Riven observes, the JIT’s syntax tree analysis will almost certainly reduce them to the same instructions.

Interesting, thanks!

Specially interesting is learning how I can analyze these things myself. :slight_smile:

Aaaaaand that explains why they get so bitchy regarding what you use for the switch statement.

I’ve tried using static variables whose value is calculated at runtime, like this:



public static int value = initValue();

public static int initValue() { return /*some operation*/; }


And it wouldn’t work. :frowning:

Thanks!

Do you normally not put a space before the question mark in your ternary? If so, it would be more readable if you have a space before the question mark. Also, parentheses would really help when you have a nested ternary operator. People suggest always putting parentheses in when working with the ternary operator, but I’d rather just use parentheses only when I have nested ternary. I’d suggest rewriting your clamp method as


public static double clamp(double value, double min, double max) {
    return value < low ? low : (value > high ? high : value);
}

The opening brace on the same line just complies with the official Java coding conventions. No big issue if you don’t want it there. :smiley: Speaking of coding conventions, I’m writing a PDF for similar coding conventions with some changes that I’ll make a topic for when I am done.

Actually yes, I never add a space after the ‘?’ in a ternary operator, visually it helps me recognize which part is the evaluation expression and which one the result.

As for parenthesis, what I often do to separate the ternary results is to linebreak and ident them.


public static double clamp(double value, double min, double max) 
{
    return value<low?    low 
                                 : value>high?   high 
                                                       : value;
}

You might also notice I put my opening braces in a newline (so my editor neatly aligns blocks vertically).

I also use coasters under drinks and favour the left side of the bed. :expressionless:

Readability is, like beauty, in the eye of the beholder. Trying to get stringent about code formatting is only acceptable in team environments.

Telling others how to visually format their code (when there’s no actual performance hit) just makes you look like a dick.

There’s already a thread about open braces. Just thought I’d point that out before there’s any more debate. ;D

I really didn’t mean to start any debate about style at all. I really should not have brought it up. I didn’t even bring up braces as a huge issue anyway :persecutioncomplex:

Sorry about doing so. I know now not to bring up style unless you’re talking about the style necessary for a project.

I follow you, but when I see a novice applying MicrosoftCodeFormattingRules then I pounce without mercy.