Wrappers of primitive types in arraylist vs arrays
Asked Answered
B

4

4

In "Core java 1" I've read

CAUTION: An ArrayList is far less efficient than an int[] array because each value is separately wrapped inside an object. You would only want to use this construct for small collections when programmer convenience is more important than efficiency.

But in my software I've already used Arraylist instead of normal arrays due to some requirements, though "The software is supposed to have high performance and after I've read the quoted text I started to panic!" one thing I can change is changing double variables to Double so as to prevent auto boxing and I don't know if that is worth it or not, in next sample algorithm

public void multiply(final double val)
    {
        final int rows = getSize1();
        final int cols = getSize2();
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                this.get(i).set(j, this.get(i).get(j) * val);
            }
        }
    }

My question is does changing double to Double makes a difference ? or that's a micro optimizing that won't affect anything ? keep in mind I might be using large matrices.2nd Should I consider redesigning the whole program again ?

Brotherly answered 29/12, 2010 at 20:45 Comment(3)
The caution is telling you about ArrayList vs primitive arrays effeciency, whereas the code sample is using neither.Bombast
the function is in a class which extends ArrayList<List<Double>>Brotherly
A small tangent: final List<Double> row = this.get(i); for (int j = 0; j < cols; j++) { row.set(j, row.get(j) * val); } will retrieve each row once in total rather than twice per column, which can speed up your code quite a bit for a rather small and easier-to-read change.Slovenia
L
4

The big issue with double versus Double is that the latter adds some amount of memory overhead -- 8 bytes per object on a Sun 32-bit JVM, possibly more or less on others. Then you need another 4 bytes (8 on a 64-bit JVM) to refer to the object.

So, assuming that you have 1,000,000 objects, the differences are as follows:

double[1000000]

8 bytes per entry; total = 8,000,000 bytes

Double[1000000]

16 bytes per object instance + 4 bytes per reference; total = 20,000,000 bytes

Whether or not this matters depends very much on your application. Unless you find yourself running out of memory, assume that it doesn't matter.

Loren answered 29/12, 2010 at 20:55 Comment(0)
E
1

It changes the place where autoboxing happens, but nothing else.

And 2nd - no, don't worry about this. It is unlikely to be a bottleneck. You can make some benchmarks to measure it for the size of your data, to prove that the difference is insignificant in regard to your application performance.

Evars answered 29/12, 2010 at 20:49 Comment(2)
Unless you used double only in which case no auto-boxing would occur. ;)Feune
yes, as far as I understood, he wants to change double to Double in order to prevent autoboxing. And it will always happen, just in another place, because he uses a List.Evars
F
1

Double is dramatically more expensive than double, however in 90% of cases it doesn't matter.

If you wanted an efficient matrix class, I would suggest you use one of the libraries which already do this efficiently. e.g. Jama.

Feune answered 29/12, 2010 at 20:50 Comment(0)
M
0

Changing the double argument into Double won't help much, it will worsen performance slightly because it needs to be unboxed for the multiplication.

What will help is preventing multiple calls to get() as in:

    for (int i = 0; i < rows; i++)
    {
        List row = this.get(i);

        for (int j = 0; j < cols; j++)
        {
            row.set(j, row.get(j) * val);
        }
    }

(btw, I guessed the type for row.)

Assuming that you use a list of lists, using iterators instead of geting and setting via loop indices will win some more performance.

Methylamine answered 29/12, 2010 at 21:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.