In this paper i will try to mention about inlining in java. Old only java developers may not think about inlining but i kknow c++ coders are very enthusiastic about…
There is an intrinsic cost associated with calling Java methods. These costs involve actual transfer of control to the method, parameter passing, return value passing, and establishment of the called method’s stack frame where local variables are stored. Such costs show up in other languages as well. In this section we will look at a few of the performance issues with methods

Perhaps the most effective way to deal with method call overhead is method inlining, either by a compiler doing it automatically, or doing it yourself manually. Inlining is done by expanding the inlined method’s code in the code that calls the method. Consider this example:

// method inlining
public class meth_inline {
public static int min(int a, int b) {
return (a < b ? a : b);
}
public static void main(String args[]) {
final int N = 10000000;
int a = 5;
int b = 17;
int c;
// call a method
Timer t = new Timer();
for (int i = 1; i <= N; i++)
c = min(a, b);
t.print("method called");
// inline the same method
t.reset();
for (int i = 1; i <= N; i++)
c = (a < b ? a : b);
t.print("method inlined");
}
}

The first case takes 6470 units of time, and the second 3364, nearly twice as fast. Note in this particular example that the JDK 1.7 just-in-time compiler will by default inline the min() method. We’ve turned off just-in-time compilation for the timings in this paper.

There are several ways that compilers can perform automatic inlining. One way is to expand the called method inline in the caller, which improves speed at the expense of code space. Another approach is more dynamic, where methods are inlined in a running program.

Note that it’s possible to make methods more attractive for inlining, by keeping them short and simple. For example, a method that simply returns the value of a private field is a prime candidate for inlining.

FINAL METHODS

One way you can help a compiler with inlining is to declare methods as final, that is, declaring that no subclass method overrides the method:

public final void f() {...}

The same technique is used with whole classes, indicating that the class cannot be subclassed, and that all its methods are implicitly final:

public final class A {...}

The idea behind use of final is this. Suppose that I have a reference to a final class A:

A aref = new A();

and I call a method f():

aref.f();

At this point I know that I really am calling A’s method f(), and not some f() in a subclass of A (because A has no subclasses). In other words, use of final provides hints about what are typically called virtual functions, that is, methods or functions that are dispatched at run time based on the type of the object that they are called for. It’s harder to inline a virtual method, since the actual method to be called cannot be determined at compile time.

SYNCHRONIZED METHODS

Synchronized methods are used in thread programming, where you want to grant a method exclusive access to a given object instance, for example so that the method can perform data structure updates without interference from other threads. Such methods are slower than non-synchronized ones, because of the overhead associated with obtaining a lock on the method’s object. Consider this code:

// synchronized methods
public class meth_sync {
public void meth1() {}
public synchronized void meth2() {}
public static void main(String args[]) {
final int N = 1000000;
meth_sync x = new meth_sync();
// non-synchronized
Timer t = new Timer();
for (int i = 1; i <= N; i++)
x.meth1();
t.print("non-synchronized");
// synchronized
t.reset();
for (int i = 1; i <= N; i++)
x.meth2();
t.print("synchronized");
}
}

INNER CLASSES

An interesting situation with method call overhead arises when you use inner classes. The inner class specification says that a private method of a class A can be used by a class B, if A encloses B. That is, if B is a class defined within A, it can call A’s private methods. Here is an example:

// methods and inner classes
public class meth_inner {
private void f() {}
class A {
A() {
f();
}
}
public meth_inner() {
A a = new A();
}
public static void main(String args[]) {
meth_inner x = new meth_inner();
}
}

A is an inner class defined within meth_inner, and A’s constructor calls a private method f() defined in meth_inner. Because the Java Virtual Machine has restrictions on calling private members from outside of their class, a special access method is generated by the compiler and added internally to the meth_inner class. This method has a name access$0(), and it in turns calls f(). In other words, a method is generated that can be called from outside of meth_inner, and grant access to a private method of meth_inner. So when f() is called above, a generated method access$0() is called, and it in turn calls f().

If you use the JDK utility program (§1.6) that disassembles .class files, by saying:

$ javap –c meth_inner

the output includes the following method definition:

Method void access$0(meth_inner)
0 aload_0
1 invokespecial #7 
4 return

This is the body of the generated method. You can avoid this overhead by avoiding use of private members in a class, assuming the class has inner classes that use those members. Obviously, however, there may be other reasons why private members are more important than the overhead associated with these generated methods.

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s