気になったので、フィールドにfinalアリ/ナシでメソッド呼び出しに差がでるかどうか確認してみました。
まあ、結論としてはどっちも一緒、なんですけど、ちょっと謎現象がありました。
インタフェースのフィールドとクラスのフィールドそれぞれfinalアリ・ナシで
リストは最後に。
結果こんな感じ。
warming up:36ms Interface Non Final:26ms -- first -- Interface Final:50ms Interface Non Final:44ms Class Final:44ms Class Non Final:41ms -- second -- Interface Final:40ms Interface Non Final:38ms Class Final:40ms Class Non Final:41ms
不思議なのは、ウォームアップ後の一回目はめちゃくちゃ速くなってるというところ。
これ、どれを最初にもってきても似たような数字になります。
というか、4つとも呼び出してるウォームアップが速いなー。
何が起こってるんだろう?
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class FinalBench { private static class InterfaceFinal{ private final List<String> list; public InterfaceFinal(List<String> list) { this.list = list; } public void proc(){ list.set(0, "123"); } } private static class InterfaceNonFinal{ private List<String> list; public void setList(List<String> list) { this.list = list; } public void proc(){ list.set(0, "123"); } } private static class ClassFinal{ private final ArrayList<String> list; public ClassFinal(ArrayList<String> list) { this.list = list; } public void proc(){ list.set(0, "123"); } } private static class ClassNonFinal{ private ArrayList<String> list; public void setList(ArrayList<String> list) { this.list = list; } public void proc(){ list.set(0, "123"); } } public static void main(String[] args) { ClassFinal cf = new ClassFinal((ArrayList<String>) Stream.of("123").collect(Collectors.toList())); ClassNonFinal cnf = new ClassNonFinal(); cnf.setList((ArrayList<String>) Stream.of("123").collect(Collectors.toList())); InterfaceFinal iff = new InterfaceFinal((ArrayList<String>) Stream.of("123").collect(Collectors.toList())); InterfaceNonFinal ifnf = new InterfaceNonFinal(); ifnf.setList((ArrayList<String>) Stream.of("123").collect(Collectors.toList())); bench("warming up", () -> { cf.proc(); cnf.proc(); iff.proc(); ifnf.proc(); }); bench("Interface Non Final", cnf::proc); System.out.println("-- first -- "); bench("Interface Final", cf::proc); bench("Interface Non Final", cnf::proc); bench("Class Final", iff::proc); bench("Class Non Final", ifnf::proc); System.out.println("-- second --"); bench("Interface Final", cf::proc); bench("Interface Non Final", cnf::proc); bench("Class Final", iff::proc); bench("Class Non Final", ifnf::proc); } static void bench(String name, Runnable proc){ for(int i = 0; i < 100; ++i){ proc.run(); } long start = System.currentTimeMillis(); for(int i = 0; i < 10_000_000; ++i){ proc.run(); } System.out.printf("%s:%dms%n", name, System.currentTimeMillis() - start); } }