6

I would like to create an application which for example measures the execution time of a certain block of code. In this case it should have a structure like this:

public static long measureExecution(String code){
    long start = System.nanoTime();
    executeCode(code); // <----
    long time = System.nanoTime() - start;

    return time;
}

I'm curious about the method designated by the arrow, I need some sort of a placeholder. How should be this method implemented? Is it even possible to execute a custom Java code inside running Java application?

I was thinking that it can be done with some sort of overriding of another methods body, but I can't quite figure out how.

Thanks for your opinions!

10
  • inb4 javaception; Please don't beat me if the question has been asked, I was looking - couldn't find it. Commented Feb 18, 2014 at 9:19
  • 1
    Have a look at AOP Commented Feb 18, 2014 at 9:19
  • 1
    What is the content of code? Is it the name of a method or is it actual java source code in the form of a string? Commented Feb 18, 2014 at 9:23
  • 1
    maybe this help you accordess.com/wpblog/… Commented Feb 18, 2014 at 9:58
  • 1
    accurate benchmarking is a complex task. Start with an existing library like openjdk.java.net/projects/code-tools/jmh Commented Feb 18, 2014 at 10:07

3 Answers 3

4

You could pass a Runnable:

public static long measureExecution(Runnable code) {
    long start = System.nanoTime();
    code.run();
    long time = System.nanoTime() - start;
    return time;
}

At the place where you call the method, use an anonymous inner class to wrap the code you want to measure:

long time = measureExecution(new Runnable() {

    @Override
    public void run() {
        System.out.println("Do something");
    }
});

(If you were using Java 8, you could use a lambda expression instead of an anonymous inner class, which would make the code shorter and easier to read).

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks! Is it possible to do this at runtime? To input the code, compile it and pass it as runnable?
You mean, someone gives your program some source code, and you want your program to compile and run it? For compiling you'd need to use the compiler API and then you'd need to load the compiled class dynamically and call it using reflection.
Yes exactly. As I wrote in the main comments:"Imagine it as a textarea on a page where user can insert his code and the press execute". Would it work with in the way you specified, please?
Yes, as I said you'd need to use the compiler API and reflection.
Thanks a lot! I've managed to get it working. Also @Karci10 provided an tutorial, which demonstrates it in a similar way accordess.com/wpblog/…
|
2

You can use OpenHFT/Java-Runtime-Compiler:

https://github.com/OpenHFT/Java-Runtime-Compiler

Also, you can use ToolProvider class (Compiler API), since java 1.6:

private Path compileJavaFile(Path javaFile, String className) {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    compiler.run(null, null, null, javaFile.toFile().getAbsolutePath());
    return javaFile.getParent().resolve(className);
}

Comments

0

You could use a Dynamic Proxy to wrap your methods invocation, here an example:

First you need to create InvocationHandler class:

public class MyInvocationHandler implements InvocationHandler {
private Object target;

public MyInvocationHandler(Object target) {
    this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    System.out.println("About to invoke " + method + "\n   with argument " + args);
    Object rv = method.invoke(target, args);
    System.out.println("   Call returned " + rv);// here you could print the time instead
    return rv;
}
}

Then Create a factory to get you object and Wrap it with the previous created proxy.

public class MyFactory {
public static MyInterface getMyInterface() {
    MyInterface mc = new MyClass();

    InvocationHandler h = new MyInvocationHandler(mc);

    MyInterface mi = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),
            new Class[] { MyInterface.class }, h);
    return mi;
}
}

Hope that help you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.