Wednesday, 17 September 2008

Head First Java 2nd Edition - Part1

One month back i and my wife Sneha started reading Head First Java 2nd Edition book.

I want to share with you few important quotations found from this book from chapter 1 - chapter10.

1) Difference between JVM and JRE.

JRE includes (JVM ) java virtual machine and some other library files. That runs a java application.

JVM - understand the corresponding byte code of a java class and make it ready for run.


The Java Runtime Environment (JRE) is a set of library files and the java executable that is kicked off in order to run any java program.


The Java Virtual Machine (JVM) is created, like a separate program, whenever a java program is executed. The JVM essentially runs between the computer and the java program. Java is designed so that any java program can run on any machine. This is because the JVM will interpret the Operating System independent java code and execute the commands needed for the particular Operating System you are trying to run the program on at the time.

2) Below are few methods how to improve speed in java programs.

a) Native methods:
If you're don't care about cross-platform portability, native methods will get you the speed of raw C (or Fortran, or C++, or...). Fallback code lets your program continue even if native methods aren't available.

b) Function inlining:
Java compilers can only inline a method if it is final, private, or static (and Hans Hall has noted that javac will only inline if a method has no local variables). If your code spends lots of time calling a method that has none of these modifiers, consider writing a version that is final.

c) Reusing objects:
It takes a long time to create an object (see Java microbenchmarks for exactly how long), so it's often worth updating the fields of an old object and reusing it rather than creating a new object. For example, rather than creating a new Font object in your paint method you can declare it as an instance object, initialize it once, and then just update it when necessary in paint (tip from Frederick Myers). Similarly, rather than allowing the garbage collector to deal with objects you've removed from a linked list, you can store them in a free list, to be reused the next time you need to add a new object (tip from Greg McClement). This can be particularly important for graphics objects like Rectangles, Points and Fonts (tip from Alexander Grosse). See also "Not using garbage collection", from JavaWorld.

d) High-level optimizations:
For a higher-level approach to optimizing the structure of object-oriented code, the online book "Object-Oriented System Development" has a chapter on performance optimization.

e) Exceptions:
You should only use exceptions where you really need them--not only do they have a high basic cost, but their presence can hurt compiler analysis (tip and code from Niklas Gustafsson).

f) The costs of Strings:
The String concatenation operator + looks innocent but involves a lot of work: a new StringBuffer is created, the two arguments are added to it with append(), and the final result is converted back with a toString(). This costs both space and time. In particular, if you're appending more than one String, consider using a StringBuffer directly instead (tip from Jason Marshall, see also space aspects in Optimizing for Size).

g) Using API classes:
Use classes from the Java API when they offer native machine performance that you can't match using Java. For example, arraycopy() is much faster than using a loop to copy an array of any significant size.

h) Replacing API classes:
Sometimes API classes do more than you need, with a corresponding increase in execution time; for these you can write specialized versions that do less but run faster. For example, in one application where I needed a container to store lots of arrays I replaced the original Vector with a faster dynamic array of objects (see "Java as an Intermediate Language"). As another example, Paule Houle has produced a set of random-number generators that are much faster than Math.random() (and have quality guarantees too).

i) Overriding API methods:
If you're using a class from the Java API and are seeing performance problems with one method, try defining a subclass which overrides that method with your own (hopefully more efficient) version.


3) Just-in-time compilation

Wikipedia says

"In computing, just-in-time compilation (JIT), also known as dynamic translation, is a technique for improving the runtime performance of a computer program. JIT builds upon two earlier ideas in run-time environments: bytecode compilation and dynamic compilation. It converts code at runtime prior to executing it natively, for example bytecode into native machine code. The performance improvement over interpreters originates from caching the results of translating blocks of code, and not simply reevaluating each line or operand each time it is met (see Interpreted language). It also has advantages over statically compiling the code at development time, as it can recompile the code if this is found to be advantageous, and may be able to enforce security guarantees. Thus JIT can combine some of the advantages of interpretation and static compilation.
"

4) Static Methods cannot use non-static methods or variables i.e instance variables.

5) A small example of showing to declare our own exceptions.


public class MyException {
public static void main(String[] args) {
try{
new ClassWhichUsesMyNewException().myMethod();
}catch(MyNewException ex) {
System.out.println(ex.getMessage());
}
}

}

class ClassWhichUsesMyNewException {

void myMethod() throws MyNewException{
String message="This is my Exception...........";
throw new MyNewException(message);
}

}

class MyNewException extends Exception{

String message = null;

MyNewException(String message){
this.message = message;
}

public String getMessage() {
return message;
}

}

No comments: