5

I have a Java program that generates a mathematical equation based on user input. I'd like to evaluate the equation, but iterating over its syntax tree is rather slow. A faster solution is to put the equation in a Java file, compile it, and call the compiled code (during runtime). Here is what I am currently doing:

  • Create an Equation.java file with the function as a static member. For example, if the equation generated is 3*x + 2*y (the real equation is much more complicated), the program would create the file

    public class Equation {
        public static DoubleBinaryOperator equation = (x, y) -> 3*x + 2*y;
    }
    
  • Compile it into Equation.class using JavaCompiler
  • Dynamically import the class file and call the equation using reflection

This is an enormous amount of boilerplate for something that seems like it should be simple. Is there an easier way of turning this equation into a function and calling it at runtime?

Mr Bingley
  • 354
  • 3
  • 10
  • 2
    And what prevents you from parsing the equation only once and create an object to represent it efficiently ? – Dici Jul 27 '15 at 22:44
  • What would that object look like? If the equation has an arbitrary number of summands, for example, I would need a way of storing those summands in a dynamic list which I would then iterate over. But then how would I evaluate each summand? Each would have to be some function object, along with some way of evaluating it, and by that time you're back to a syntax tree. – Mr Bingley Jul 27 '15 at 23:07
  • Possible dupe of http://stackoverflow.com/questions/4166135/dynamic-code-execution – yshavit Jul 27 '15 at 23:14
  • @MrBingley Mmmm that's true. However, I think the lambda notation enables to inline the code of the methods called on the objects it involves. If it is correct, you would be able to implement a conversion from an AST to an inlined, single expression. I tried implementing that but have still no evidence it does whant I want – Dici Jul 28 '15 at 00:08
  • What are the operands? What is the domain of the function? Do you know the number of variables in advance, or at least, as a previous step? – fps Jul 28 '15 at 01:24

2 Answers2

1

Depending on how complex your equation is, the JavaScript evaluation engine Nashorn might be worth a try.

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Object o = engine.eval("1 + 2 * 3");
System.out.println(o); // prints 7

Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("x", 10);

System.out.println(engine.eval("x + 1")); // prints 11
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
  • I don't think it meets the requirements. FIrst, your example is not an equation (just an expression), then it seems the OP wants a fine grain control on the equation, whereas your proposition delegates everything to external code – Dici Jul 27 '15 at 22:46
  • 1
    Check the updated code. Why do you think the OP needs fine control over the equation? He would have that when evaluating the AST, but apparently that doesn't seem efficient enough. Invoking a `JavaCompiler` is delegation to external code as well. – Clashsoft Jul 27 '15 at 22:49
  • If he wants *finest* control over the equation -> JVM transition, he could compile the AST to bytecode using a framework like [ASM](http://asm.ow2.org/), and load the generated code using `Unsafe.defineAnonymousClass`. But for someone who is not familiar with Java bytecode and compilation in general, this is more than overkill. – Clashsoft Jul 27 '15 at 22:52
0

why you have to compile it on runtime .. compile as it jar .. and save it to a folder .. load it on runtime ..

here is an usefull answer how to load jar file

How to load a jar file at runtime

Community
  • 1
  • 1
Saltuk
  • 1,159
  • 9
  • 12
  • 1
    Because the equation is only known after the user types in some input. We don't know what it is until the program is already running. – Mr Bingley Jul 27 '15 at 23:17
  • the formul is writing by user and you want to solve it right ? .. then why not use antlr ? .. – Saltuk Jul 27 '15 at 23:21