EeBlog(テクニカルブログ)

第14回 プロパティキャッシュ

仕事でプログラムを組んでいると、性能向上ということで動作速度を求められることは少なくありません。
今回はスピードアップの方法として「プロパティキャッシュ」という技法を紹介したいと思います。
技術としては非常に簡単なものですので皆さんも無意識に行っているかもしれません。

オブジェクト指向の言語では参照型を戻すメソッドやフィールドがつながることが多々あります。
例えば、

System.out.println(“abc”);

上記の文は、SystemクラスがoutフィールドでPrintWriter型を返し、 そのPrintWriterクラスのprintlnメソッドを使用しています。

こういった複数の参照がつながっている参照が、 数回出てくるようなコードに対して今回の「プロパティキャッシュ」は 有効です。
参照を一旦変数に代入し、その変数を使用します。

以下のサンプルではA~Eまでのクラスがあり、 AはB型の参照を返し、BはC型の参照を返します。
つまり、Eにあるメソッドを使う際には、

a.getB().getC().getD().getE().method();

となります。

a.getB().getC().getD().getE()

までを変数に入れることでスピードの向上につながります。

尚、サンプルはマシン性能に左右されますので、 ループ回数(MAX)を変更して試してみてください。

public class PropertyCache {

     public static void main(String[] args) {

         final int MAX = 100000000;
         long time = 0;

         A a = new PropertyCache().new A();

         // キャッシュなし
         time = System.currentTimeMillis();
         for (int i = 0; i < MAX; i++) {
             a.getB().getC().getD().getE().method();
         }
         System.out.println(System.currentTimeMillis() - time);

         // キャッシュあり
         time = System.currentTimeMillis();
         E e = a.getB().getC().getD().getE();
         for (int i = 0; i < MAX; i++) {
             e.method();
         }
         System.out.println(System.currentTimeMillis() - time);

     }

     class A {
         private B b = new B();
         public B getB() { return b; }
     }
     class B {
         private C c = new C();
         public C getC() { return c; }
     }
     class C {
         private D d = new D();
         public D getD() { return d; }
     }
     class D {
         private E e = new E();
         public E getE() { return e; }
     }
     class E {
         public void method() {
         }
     }

 }

「このフェラーリ、キャッシュで!!」って言ってみたい…。