Jason S
Jason S

Reputation: 189696

Java: most efficient way to defensively copy an int[]?

I have an interface DataSeries with a method

int[] getRawData();

For various reasons (primarily because I'm using this with MATLAB, and MATLAB handles int[] well) I need to return an array rather than a List.

I don't want my implementing classes to return the int[] array because it is mutable. What is the most efficient way to copy an int[] array (sizes in the 1000-1000000 length range) ? Is it clone()?

Upvotes: 6

Views: 710

Answers (3)

Kevin Bourrillion
Kevin Bourrillion

Reputation: 40851

  1. No one ever solved their app's performance problems by going through and changing arraycopy() calls to clone() or vice versa.

  2. There is no one definitive answer to this question. It isn't just that it might be different on different VMs, versions, operating systems and hardware: it really is different.

  3. I benchmarked it anyway, on a very recent OpenJDK (on a recent ubuntu) and found that arraycopy is much faster. So is this my answer to you? NO! Because if it proves to be true, there's a bug with the intrinsification of Arrays.copyOf, and that bug will likely get fixed, so this information is only transient to you.

Upvotes: 7

BalusC
BalusC

Reputation: 1108802

The only alternative is Arrays#copyOf() (which uses System#arrayCopy() under the hoods).

Just test it.

package com.stackoverflow.q2830456;

import java.util.Arrays;
import java.util.Random;

public class Test {

    public static void main(String[] args) throws Exception {
        Random random = new Random();
        int[] ints = new int[100000];
        for (int i = 0; i < ints.length; ints[i++] = random.nextInt());

        long st = System.currentTimeMillis();
        test1(ints);
        System.out.println(System.currentTimeMillis() - st);

        st = System.currentTimeMillis();
        test2(ints);
        System.out.println(System.currentTimeMillis() - st);
    }

    static void test1(int[] ints) {
        for (int i = 0; i < ints.length; i++) {
            ints.clone();
        }
    }

    static void test2(int[] ints) {
        for (int i = 0; i < ints.length; i++) {
            Arrays.copyOf(ints, ints.length);
        }
    }

}
20203
20131

and when test1() and test2() are swapped:

20157
20275

The difference is negligible. I'd say, just go for clone() since that is better readable and Arrays#copyOf() is Java 6 only.

Note: actual results may depend on platform and JVM used, this was tested at an Dell Latitude E5500 with Intel P8400, 4GB PC2-6400 RAM, WinXP, JDK 1.6.0_17_b04

Upvotes: 7

jonathanasdf
jonathanasdf

Reputation: 2894

http://www.javapractices.com/topic/TopicAction.do?Id=3

the numbers will likely be different depending on your specs, but seems clone is the best choice.

Upvotes: 1

Related Questions