1
class Testing{
    private static int counter;
    private static int[] intArray;
    public static ReturnClassName className(File f){
        ReturnClassName returnCN= new ReturnClassName();
        byte[] b;
        try{
            DataInputStream dataIStream= new DataInputStream(new FileInputStream(f));
            intArray= new int[dataIStream.available()];
            b= new byte[dataIStream.available()];
            dataIStream.read(b);
            intArray= b;
            // setting methods for ReturnClassName 
            // counter increment
            returnCN.setNumber(someMethod(5));
            }//catch() block

    return returnCN;
}
private static int[] someMethod(int l){
    return Arrays.copyOfRange(intArray, counter, counter + l);
}

Or

class Testing{
    private static int counter;
    public static ReturnClassName className(File f){
        ReturnClassName returnCN= new ReturnClassName();
        byte[] b;
        try{
            DataInputStream dataIStream= new DataInputStream(new FileInputStream(f));
            intArray= new int[dataIStream.available()];
            b= new byte[dataIStream.available()];
            dataIStream.read(b);
            intArray= b;
            // setting methods for ReturnClassName 
            // counter increment
            returnCN.setNumber(someMethod(intArray,5));

    }//catch() block

    return returnCN;
}

private static int[] someMethod(int[] iArray, int l){

    return Arrays.copyOfRange(iArray, counter, counter + l);
}

I want to know which one is more optimized and safe of the above two codes. Also while passing the array in the 2nd code, is it passing the whole array or just the address of that array. Like both intArray and iArray are pointing to the same integer array?

OnePunchMan
  • 720
  • 15
  • 33

1 Answers1

1

Arrays are passed by reference so both snippets are equivalent concerning efficiency except for the fact that if you are not using intArray for some other purpose: The second version will unreference the array and make it a candidate for garbage collection.

This is, in the second case, the array will be a candidate to be collected as soon as someMethod execution returns whereas the first version will keep the array referenced until the program ends since it is static.

From your comments I understand that you will call className once per file for different files and for each file you will call 'someMethod' many times. Then I like a solution similar to the firstone at some points but different to both the first and the second one.

That solution is to have a instance of Testing for each file you load data from:

  1. Force each instance to be associated with a concrete file.
  2. Make methods and attributes not static. This is for each Testing element to have its own data loaded from its file.
  3. Change className so it will load data from its file only once.
  4. Make a right user of Testing and its instances.

    class Testing{
    
        public Testing(File f)
        {
            this.f = f;
        }
    
        private File f;
        private int[] intArray;
        public static ReturnClassName className(){
            ReturnClassName returnCN= new ReturnClassName();
            byte[] b;
            if(intArray == null || intArray.length > 0) return //If it was called before, then we don't load the file again.
            {
                try{
                    DataInputStream dataIStream= new DataInputStream(new FileInputStream(f));
                    intArray= new int[dataIStream.available()];
                    b = new byte[dataIStream.available()];
                    dataIStream.read(b);
                    intArray= b;
                    // setting methods for ReturnClassName 
                    // counter increment
                } catch(Exception e) { 
                ...
                ...
                }
            }
            returnCN.setNumber(someMethod(5));
            return returnCN;
        }
    
        private int[] someMethod(int l){
            return Arrays.copyOfRange(intArray, counter, counter + l);
        }
    }
    

Example of use:

Testing forFile1 = new Testing(fileObj01);
ReturnClassName x = ReforFile1.className();
ReturnClassName y = ReforFile1.className();

Testing forFile2 = new Testing(fileObj02);
ReturnClassName z = ReforFile2.className();
ReturnClassName w = ReforFile2.className();

You could, on the other hand, implement a better solution were you have a map of integer arrays indexed by the input file (like a cache) and you keep a copy if their bytes on it. Having thus a single instance od Testing and keep File f as input parameter for 'className'.

  • if I am going to use the someMethod frequently, which code is more preparable.. I mean which one will execute faster? – OnePunchMan Apr 16 '14 at 09:30
  • @kaze If you are not regenerating `intArray` before each `someMethod` call then the first one but removing possible `intArray` repeated constructions. If you have to generate new values for `intArray` each time then both codes are equivalent except for the details remarked by "mok" (answer above) and the fact that the values generates for the last call won't be collected (check my answer). To sum up, I would only use a modified version of the first case (generating `intArray` just once) if the values of `intArray` are always the same. – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 09:36
  • I am not going to reinitialized 'intArray' before calling 'someMethod' again, as you can see in the code, I am passing the 'intArray' to 'someMethod' only to get a subpart of the 'intArray'. What do you mean by "generating 'intArray' just once"? – OnePunchMan Apr 16 '14 at 09:47
  • @kaze Think just a second about the second solution: Are you going to call `someMethod` from outside `className`? If that is the case, wich parameter would you pass to it? – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 09:58
  • the above two methods are the only methods in my class Testing. what i thought was if I am using the second code, the execution time might be longer than the first one (because I am passing the array and also I am going to run it in a low processor, CPU). Is my assumption correct? – OnePunchMan Apr 16 '14 at 09:59
  • @kaze I do not think it is correct being the code as it is. Arrays are being passed as references. I don't know what use is your class but I can tell you that the only difference at execution time you can get is if you are calling 'className' method many times. In that case you should avoid reading the file. How? By making `intArray` (even `byteArray`) attributes and filling them (throught reading the file) only the first time you call 'className'. – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 10:04
  • That's only I am doing in both the above cases. I am passing the file in the 'className' method, and getting the integer datas as a 'ReturnClassName' object. In order to read the file contents I need to 1st create the byte array and put the values in integer array. thats all. For each different files, 'className' have to be called again. But for the same file, its called only once. – OnePunchMan Apr 16 '14 at 10:16
  • @kaze In that case definitely the second option is better for the reasons exposed. You won't detect any significant time difference but, for the second case, all the size of `intArray` will be collected soon after `className` has returned. – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 10:21
  • but you told that if I am not regenerating intArray, the first option is more preferrable as I am calling 'someMethod' frequently inside 'className' method. – OnePunchMan Apr 16 '14 at 10:34
  • @kaze Yes but only the calls are for the same file having `intArray` thus always the same values. You just told me repeated calls would imply different files. Besides, I told you that you would have to change the implementation a little bit. – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 10:36
  • can you give some idea how change the implementation? – OnePunchMan Apr 16 '14 at 10:39
  • returnCN.setNumber(someMethod(5)) is one of the setting methods so I just need to include it inside try block... and also remove the 'static' modifier from 'className' – OnePunchMan Apr 16 '14 at 11:14
  • @kaze Change those details, I just gave you the structure. At catch block there are points instead of code... – Pablo Francisco Pérez Hidalgo Apr 16 '14 at 11:24