Advertisement
Guest User

Memoize

a guest
Dec 18th, 2014
780
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.90 KB | None | 0 0
  1. import java.lang.invoke.MethodHandle;
  2. import java.lang.invoke.MethodHandles;
  3. import java.lang.reflect.Method;
  4. import java.util.Arrays;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. public class Memoize {
  9.  
  10.     public interface MemoizedFunction<V> {
  11.         V call(Object... args);
  12.     }
  13.  
  14.     private static class ArgList {
  15.         public Object[] args;
  16.  
  17.         @Override
  18.         public boolean equals(Object o) {
  19.             if (this == o) {
  20.                 return true;
  21.             }
  22.             if (!(o instanceof ArgList)) {
  23.                 return false;
  24.             }
  25.  
  26.             ArgList argList = (ArgList) o;
  27.  
  28.             // Probably incorrect - comparing Object[] arrays with Arrays.equals
  29.             return Arrays.equals(args, argList.args);
  30.         }
  31.  
  32.         @Override
  33.         public int hashCode() {
  34.             return args != null ? Arrays.hashCode(args) : 0;
  35.         }
  36.     }
  37.  
  38.     public static <V> MemoizedFunction<V> memoizeFunction(Class<? super V> returnType, Method method) throws
  39.                                                                                                       IllegalAccessException {
  40.         final Map<ArgList, V> memoizedCalls = new HashMap<>();
  41.         MethodHandles.Lookup lookup = MethodHandles.lookup();
  42.         MethodHandle methodHandle = lookup.unreflect(method)
  43.                                           .asSpreader(Object[].class, method.getParameterCount());
  44.         return args -> {
  45.             ArgList argList = new ArgList();
  46.             argList.args = args;
  47.             return memoizedCalls.computeIfAbsent(argList, argList2 -> {
  48.                 try {
  49.                     //noinspection unchecked
  50.                     return (V) methodHandle.invoke(args);
  51.                 } catch (Throwable throwable) {
  52.                     throw new RuntimeException(throwable);
  53.                 }
  54.             });
  55.         };
  56.     }
  57.  
  58.     public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException {
  59.         Method slowFunctionMethod = Memoize.class.getMethod("slowFunction", int.class);
  60.  
  61.         MemoizedFunction<Integer> cachingSlowFunction = Memoize.memoizeFunction(Integer.class, slowFunctionMethod);
  62.  
  63.         long startSlow = System.currentTimeMillis();
  64.         int result = cachingSlowFunction.call(2);
  65.         long endSlow = System.currentTimeMillis();
  66.         // Do it again!
  67.         long startFast = System.currentTimeMillis();
  68.         int result2 = cachingSlowFunction.call(2);
  69.         long endFast = System.currentTimeMillis();
  70.  
  71.         System.out.printf("The first time took %dms%n", endSlow - startSlow);
  72.         System.out.printf("The second time took %dms%n", endFast - startFast);
  73.     }
  74.  
  75.     public static int slowFunction(int input) {
  76.         try {
  77.             Thread.sleep(1000);
  78.         } catch (InterruptedException e) {
  79.             e.printStackTrace();
  80.         }
  81.         return input * 2;
  82.     }
  83. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement