compareTo() for primitive types?

A

Andreas Leitgeb

Suppose I've got a class that contains an "int" field.
Then I want to make my class "Comparable", and the
order depends on the int-field.

what's the standard idiom to use in the overridden
compareTo method?

return that.intVar - this.intVar;
is surely wrong, due to wraparound, as one can see when
comparing MAX_VALUE to MIN_VALUE
Using Integer.compareTo() involves boxing twice, which feels
too heavy.

Does one need to nest two ?:-operations (or if's), or is
there some nicer idiom?
 
M

Mark Jeffcoat

Andreas Leitgeb said:
Suppose I've got a class that contains an "int" field.
Then I want to make my class "Comparable", and the
order depends on the int-field.

what's the standard idiom to use in the overridden
compareTo method?

return that.intVar - this.intVar;
is surely wrong, due to wraparound, as one can see when
comparing MAX_VALUE to MIN_VALUE
Using Integer.compareTo() involves boxing twice, which feels
too heavy.

Does one need to nest two ?:-operations (or if's), or is
there some nicer idiom?

Either one will work, in almost every domain, but I'd
go ahead and use Integer's compareTo(), since it's already
written and makes it obvious that you're not doing anything
unusual.

You've likely already spent more time thinking about this
than will be spent boxing and unboxing primitives in
the lifetime of every program you'll ever write during
your career. Don't fear the wrapper classes.
 
D

djthomp

Suppose I've got a class that contains an "int" field.
Then I want to make my class "Comparable", and the
order depends on the int-field.

what's the standard idiom to use in the overridden
compareTo method?

return that.intVar - this.intVar;
is surely wrong, due to wraparound, as one can see when
comparing MAX_VALUE to MIN_VALUE
Using Integer.compareTo() involves boxing twice, which feels
too heavy.

Does one need to nest two ?:-operations (or if's), or is
there some nicer idiom?

You might take a look at the implementation of Integer.compareTo(). I
seem to recall it does something like:

if (thisVal < anotherVal)
return -1;
else if (thisVal > anotherVal)
return 1;
else
return 0;
 
A

Andreas Leitgeb

You might take a look at the implementation of Integer.compareTo(). I
seem to recall it does something like:
if (thisVal < anotherVal)
return -1;
...

< From: Mark Jeffcoat <[email protected]>
< You've likely already spent more time thinking about this
< than will be spent boxing and unboxing primitives in
< the lifetime of every program you'll ever write during
< your career. Don't fear the wrapper classes.

Ok, thanks to both! I think 99% of situations will be fine
with Integer.compareTo()+boxing, the rest I'll have to do
with "if ... else if ... else ...".

PS: I hoped to have missed something like python's <=> operator.
 
C

Chris Uppal

Mark said:
Either one will work, in almost every domain, but I'd
go ahead and use Integer's compareTo(), since it's already
written and makes it obvious that you're not doing anything
unusual.

You've likely already spent more time thinking about this
than will be spent boxing and unboxing primitives in
the lifetime of every program you'll ever write during
your career. Don't fear the wrapper classes.

My gut feeling is that this is probably false -- autoboxing is /not/ free and
if used with large amounts of data, or in contexts where the number of
operations is more than linear in the amount of data (as is the case for
sorting -- the OP's target application) then it should not be used lightly.

This is /especially/ true since the direct representation (either as a double
conditional, or by doing the simple arithmetic with longs) is at least as
transparent as invoking the stuff in Integer.

-- chris
 
M

Mark Jeffcoat

Chris Uppal said:
My gut feeling is that this is probably false -- autoboxing is /not/ free and
if used with large amounts of data, or in contexts where the number of
operations is more than linear in the amount of data (as is the case for
sorting -- the OP's target application) then it should not be used lightly.

It's possible that I'm exaggerating, but I've never
seen anything in a profiler that suggested that it
might be causing a problem, and I have strong allergies
to thinking about performance concerns at all during
normal development.

I suspect the JIT compiler does something clever
in the simpler cases. My gut feeling is that inlining
Integer.compareTo() is a simpler case, but I'd yield
to contrary profiling.
 
M

Mark Rafn

You've likely already spent more time thinking about this
It's possible that I'm exaggerating, but I've never
seen anything in a profiler that suggested that it
might be causing a problem, and I have strong allergies
to thinking about performance concerns at all during
normal development.

This depends a LOT on the type of application you're writing. In most
business logic, Chris is completely right - just do what's clearest to the
developers and most provably correct, worrying about microperformance a lot
less than your overall algorithms unless the profiler says otherwise.
I suspect the JIT compiler does something clever
in the simpler cases.

Additionally, Sun's wrapper objects cache autobox objects for 256 values
near 0. However, Mark's right too: it's not magic. There _IS_ a hit for
this, and if you're writing an app where you think it's important, you're
probably right, and you should take the time to do the right thing (and
document that you've thought about and covered the edge cases).
My gut feeling is that inlining Integer.compareTo() is a simpler case, but
I'd yield to contrary profiling.

Yup, that about covers it.
 
M

Mark Jeffcoat

This depends a LOT on the type of application you're writing. In most
business logic, Chris is completely right - just do what's clearest to the
developers and most provably correct, worrying about microperformance a lot
less than your overall algorithms unless the profiler says otherwise.


Additionally, Sun's wrapper objects cache autobox objects for 256 values
near 0. However, Mark's right too: it's not magic. There _IS_ a hit for
this, and if you're writing an app where you think it's important, you're
probably right, and you should take the time to do the right thing (and
document that you've thought about and covered the edge cases).

You've switched the references, here: I'm defending the
idea of ignoring any potential performance hit from boxing
primitives.

The key difference of opinion, I suspect, is in your last
paragraph: I think that intelligent, experienced, well-meaning
programmers will be wrong about the magnitude (and occasionally
even the direction) of performance choices like this when
they try to make those decisions ahead of time.

(I admit occasional exceptions; for example, when your
entire program is to implement a single algorithm. Even
so, why cultivate bad habits?)
 
D

Daniel Pitts

djthomp said:
You might take a look at the implementation of Integer.compareTo(). I
seem to recall it does something like:

if (thisVal < anotherVal)
return -1;
else if (thisVal > anotherVal)
return 1;
else
return 0;

In JDK 1.5.0_05 src.zip, the Integer.compareTo implementation is:

public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
 
A

Andreas Leitgeb

Daniel Pitts said:
In JDK 1.5.0_05 src.zip, the Integer.compareTo implementation is:
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

If (back to the original usecase) that one int-field isn't the
last criterion of some cascade, then

// previous criteria...
if (that.intVar > this.intVar) return 1;
if (that.intVar < this.intVar) return -1;
// continue with next criterion...

is probably both clearest and fastest, I'd guess.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top