开发者

Is that how 'Long' works (in Java)?

Look at this Java code:

class PerformanceTest2{

    public static void main(String args[]){

        Long sum = 0L;

        for(int i=0;i<Integer.MAX_VALUE;i++)
            sum += i;

        Sy开发者_StackOverflow中文版stem.out.println("Sum = " + sum);
    }
} 

It is observed that it takes longer for this code since sum is 'Long' & not 'long'. So in every iteration what happens is:

sum = new Long(sum.longValue() + i); (for sum+=i;)

So, a new object is created every time. Doesn't Java support C++ like feature of returning a reference so that we could've written (possibly):

sum.longValue() += i;

possibly not having to create sum object every time around the loop? Am I right?


Well, it doesn't call the constructor. It uses:

for (int i = 0; i < Integer.MAX_VALUE; i++)
{
   long tmp = sum.longValue(); // Unboxing
   tmp += i;
   sum = Long.valueOf(tmp); // Boxing
}

The wrapper objects are deliberately immutable - they could easily have been designed to be mutable, but immutability is often a very useful feature. If you want to write your own mutable wrapper type, you're very welcome to - at which point you could have code such as:

LongWrapper sum = new LongWrapper(0L);
for (int i = 0; i < Integer.MAX_VALUE; i++)
{
    sum.add(i);
}
System.out.println("Sum = " + sum);

Or possibly:

LongWrapper sum = new LongWrapper(0L);
for (int i = 0;i < Integer.MAX_VALUE; i++)
{
    sum.setValue(sum.getValue() + i);
}
System.out.println("Sum = " + sum);


I invite you to take a look at the testcases I've set up here:

http://ideone.com/Hvbs1

Your code is slow not because you are mixing long and int types, but because you are using Long instead of long. The Long type is a proper object, and immutable to boot, so every time you assign a new value to your variable, a new object is being constructed (a possible exception is if a cached object already exists for the new value). This is an expensive operation (relatively speaking).

As you will see from the example code, changing the loop to add a long instead of an int does not make it run any faster. The way to speed it up is to change the first variable to a long instead of a Long.


Java has no C++ like references. Also, the built-in wrapper classes for primitive types are deliberately made immutable. One of the reasons for this decision is, that the run-time may then cache the wrapper instances for particular values, and avoid having to create a new object (this requires, that you call valueOf instead of allocating a new object via new; the compiler does this for boxing).


So, a new object is created every time. Doesn't Java support C++ like feature of returning a reference so that we could've written (possibly): ...

If you use Long you are explicitly requesting wrapper type from Java. And the convention for wrapper types is: they are immutable. And immutability (as constness in C++) requires that no modifiable internals must be given to the outside. But a C++ like reference would exactly do that. (Let's skip the const reference part because that also wouldn't help you in C++.)

possibly not having to create sum object every time around the loop? Am I right?

Theoretically yes, but if you want that behaviour, why don't you use not a plain long right from the start?


Others have already explained why Long takes longer then long and how usingLong.valueOf` may be slightly faster.

Please, don't let this be a reason for not using Long. In all likelihood your overall system throughput time will not be affected by it.

If there are tight loops where this affects performance then use the primitive long there, a hand-rolled wrapper as Jon describes or MutableLong from apache commons.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜