Java : メソッド呼び出しの効率調査
ばかばかしいと言われようが、無駄だと言われようが、納得いくまで調査するのが信条ですから。それに、効果がないことが分かるというのも、有意な結果です。
1.デフォルトコンストラクタと普通のコンストラクタ
public final class A { String s0; String s1; A(String s0, String s1) { this.s0 = s0; this.s1 = s1; } } public final class B { String s0; String s1; } public final class Main { public static void main(String[] args) { int l = Integer.parseInt(args[0]); int s = 0; if(args[1].equals("A")){ for (int i=0; i<l; ++i) { A a = new A("a","b"); s += a.s0.length(); } }else{ for (int i=0; i<l; ++i) { B b = new B(); b.s0 = "a"; b.s1 = "b"; s += b.s0.length(); } } System.out.println(s); } }
結果は、変化なし。
$ time java Main 100000000 A 100000000 real 0m11.545s user 0m0.010s sys 0m0.050s $ time java Main 100000000 B 100000000 real 0m11.582s user 0m0.010s sys 0m0.050s $ time java Main 300000000 A 300000000 real 0m33.765s user 0m0.020s sys 0m0.030s $ time java Main 300000000 B 300000000 real 0m33.556s user 0m0.010s sys 0m0.050s
2.抽象クラスとインターフェース
public interface AIntf { int get(); } public abstract class ASuper { public abstract int get(); } public class A extends ASuper implements AIntf { public int get() { return 1;} } public final class Main { public static void main(String[] args) { int l = Integer.parseInt(args[0]); int s = 0; if (args[1].equals("interface")) { AIntf a = new A(); for (int i=0; i<l; ++i) { s += a.get(); } }else{ ASuper a = new A(); for (int i=0; i<l; ++i) { s += a.get(); } } System.out.println(s); } }
結果は、抽象クラスの方が効率的らしい。
$ time java Main 200000000 interface 200000000 real 0m5.271s user 0m0.030s sys 0m0.030s $ time java Main 200000000 super 200000000 real 0m3.425s user 0m0.010s sys 0m0.040s $ time java Main 200000000 interface 200000000 real 0m5.231s user 0m0.010s sys 0m0.050s $ time java Main 200000000 super 200000000 real 0m3.423s user 0m0.010s sys 0m0.040s
3.ExceptionとRuntimeException
public final class Main { static int a(int i) throws Exception { if (i<0) { throw new Exception(); }else if(i==0) { return 1; }else{ return a(i-1); } } static int b(int i) { if (i<0) { throw new RuntimeException(); }else if(i==0) { return 1; }else{ return b(i-1); } } static int c(int i) { if (i<0) { return -1; }else if(i==0) { return 1; }else{ return c(i-1); } } public static void main(String[] args) { int l = Integer.parseInt(args[0]); int s = 0; if (args[1].equals("exception")) { try{ for (int i=0; i<l; ++i) { s += a(10); } }catch(Exception e){} }else if (args[1].equals("runtimeexception")){ try{ for (int i=0; i<l; ++i) { s += b(10); } }catch(RuntimeException e){} }else{ try{ for (int i=0; i<l; ++i) { s += c(10); } }catch(Exception e){} } System.out.println(s); } }
結果は、差はないといえそう。
$ time java Main 30000000 exception 30000000 real 0m6.800s user 0m0.010s sys 0m0.040s $ time java Main 30000000 runtimeexception 30000000 real 0m6.744s user 0m0.030s sys 0m0.030s $ time java Main 30000000 none 30000000 real 0m7.163s user 0m0.020s sys 0m0.030s