Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.lang.invoke.MethodHandle;
- import java.lang.invoke.MethodHandles;
- import java.lang.reflect.Method;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- public class Memoize {
- public interface MemoizedFunction<V> {
- V call(Object... args);
- }
- private static class ArgList {
- public Object[] args;
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof ArgList)) {
- return false;
- }
- ArgList argList = (ArgList) o;
- // Probably incorrect - comparing Object[] arrays with Arrays.equals
- return Arrays.equals(args, argList.args);
- }
- @Override
- public int hashCode() {
- return args != null ? Arrays.hashCode(args) : 0;
- }
- }
- public static <V> MemoizedFunction<V> memoizeFunction(Class<? super V> returnType, Method method) throws
- IllegalAccessException {
- final Map<ArgList, V> memoizedCalls = new HashMap<>();
- MethodHandles.Lookup lookup = MethodHandles.lookup();
- MethodHandle methodHandle = lookup.unreflect(method)
- .asSpreader(Object[].class, method.getParameterCount());
- return args -> {
- ArgList argList = new ArgList();
- argList.args = args;
- return memoizedCalls.computeIfAbsent(argList, argList2 -> {
- try {
- //noinspection unchecked
- return (V) methodHandle.invoke(args);
- } catch (Throwable throwable) {
- throw new RuntimeException(throwable);
- }
- });
- };
- }
- public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException {
- Method slowFunctionMethod = Memoize.class.getMethod("slowFunction", int.class);
- MemoizedFunction<Integer> cachingSlowFunction = Memoize.memoizeFunction(Integer.class, slowFunctionMethod);
- long startSlow = System.currentTimeMillis();
- int result = cachingSlowFunction.call(2);
- long endSlow = System.currentTimeMillis();
- // Do it again!
- long startFast = System.currentTimeMillis();
- int result2 = cachingSlowFunction.call(2);
- long endFast = System.currentTimeMillis();
- System.out.printf("The first time took %dms%n", endSlow - startSlow);
- System.out.printf("The second time took %dms%n", endFast - startFast);
- }
- public static int slowFunction(int input) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return input * 2;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement