Code Optimization : Effective Java Chapter 2 : Item 5 : Avoid Creating unnecessary Objects

Code Optimization : Effective Java Chapter 2 : Item 5 : Avoid Creating unnecessary objects

  1. Reuse can be both faster and morestylish. An object can always be reused if it is immutable.
  2. String s = "stringette";
  3. This version uses a single String instance, rather than creating a new one each time it is executed.

  4. In the below mentioned code we are creating date object inside the , and we should not do it that way since what will happen every time we will call the method the same object is being created, whereas a better approach will be to use the same DATE object. ```java

public class Person { private final Date birthDate; // Other fields, methods, and constructor omitted public boolean isBabyBoomer() { // Unnecessary allocation of expensive object

Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);

Date boomStart = gmtCal.getTime();

gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);

Date boomEnd = gmtCal.getTime();

return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd)<0;} }




- **Optmized way of the above class is** 
```java

class Person {
private final Date birthDate;
// Other fields, methods, and constructor omitted
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;

static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();

}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
Prefer Primitive over autoboxed
  • Not so optmized code
// Hideously slow program! Can you spot the object creation?
public static void main(String[] args) {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
  • above code will give correct answer and logic is also correct, but since we have used here Long instead of long so it will create
  • The variable sum is declared as a Long instead of a long, which means that the program constructs about 231 unnecessary Long instances (roughly one for each time the long i is added to the Long sum).
Code sample Not optimized
public class Improve {  
    public static void main(String[] args){  
      System.out.println("hello world");  

      long startTime=System.currentTimeMillis();  

      //find how much memory is taken by the program  

      Runtime runtime=Runtime.getRuntime();  
      long before,after;  
      System.gc();  

      before=runtime.freeMemory();  
      Long sum=0L;  
      for(long i=0 ; i< Integer.MAX_VALUE;i++) {  
          sum=sum+i;  
      }  

      after=runtime.freeMemory(); //it tells amount of free memory in jvm  
      System.out.println("Memory used "+ (before-after));   // this will be before-after : free memory will decrease right  

      long endTime=System.currentTimeMillis();  
      System.out.println("Time Taken "+ (endTime-startTime));  
      System.out.println(sum);  
    }  
}

Output

Memory used -48176240
Time Taken 6187    
2305843005992468481
After optimized code
  • just converted Long to long and there is vast improvemen in code it means improve memory usage improves performance
  • prefer primitives to boxed primitives, and watch out for unintentional autoboxing.

    public class Improve {  
      public static void main(String[] args){  
        System.out.println("hello world");  
    
        long startTime=System.currentTimeMillis();  
    
        //find how much memory is taken by the program  
    
        Runtime runtime=Runtime.getRuntime();  
        long before,after;  
        System.gc();  
    
        before=runtime.freeMemory();  
        long sum=0L;  
        for(long i=0 ; i< Integer.MAX_VALUE;i++) {  
            sum=sum+i;  
        }  
    
        after=runtime.freeMemory(); //it tells amount of free memory in jvm  
        System.out.println("Memory used "+ (before-after));   // this will be before-after : free memory will decrease right  
    
        long endTime=System.currentTimeMillis();  
        System.out.println("Time Taken "+ (endTime-startTime));  
        System.out.println(sum);  
      }  
    }
    

Output

Memory used 2663400
Time Taken 754
2305843005992468481