This project has moved. For the latest updates, please go here.

Compile Once?

Sep 2, 2014 at 7:30 PM
I'm trying to use Jurassic in a real-time application, specifically a Unity game. It's working very well for me, but I'm having issues with performance. I have a script executed every frame through Jurassic, and if that script has any significant length it takes up most of my frame on it's own. (A script of roughly 100 lines takes roughly 25ms to execute, for example.)

What I actually do in the script doesn't matter, I can do all the math I want.
var j = 0;
for(var i = 0; i < 1000; i++)
{
     j += i;
}
outperforms
var i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
by a factor of two. Execution's fast. What's slowing down my program is the compilation time, because right now calling Execute on the same string twice seemingly recompiles the code each time. Is there a way to make Jurassic compile only at startup? Am I wrong about what's causing the slowdown? Am I using Jurassic for something it was never meant to be used for and I should give up and find a different solution?

Thanks!
-Lou
Coordinator
Sep 2, 2014 at 9:55 PM
Check out ScriptEngine.Evaluate(ScriptSource) in the Jurassic source code. What you want to do is pretty much covered by the EvalMethodGenerator class -- however, that is unfortunately an internal class so it's not directly usable. How about if I add a simple CompiledScript class that wraps the EvalMethodGenerator class?
Sep 3, 2014 at 6:33 PM
That would be excellent! Thank you!
Coordinator
Sep 5, 2014 at 9:12 AM
OK done :-)
Sep 7, 2014 at 3:23 PM
Thank you so much. This is a huge help. :)

I'm having a new, smaller issue now, though.

I can build the dll from source, with warnings but no errors. However, I'm getting a run-time error when I try to Execute() a script. (I haven't gotten to try the new functionality yet. but this really seems like I'm building the dll incorrectly somehow.)
NotImplementedException: The requested feature is not implemented.
System.Reflection.Emit.DynamicMethod.GetDynamicILInfo () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs:229)
Jurassic.Compiler.DynamicILGenerator..ctor (System.Reflection.Emit.DynamicMethod) <IL 0x0001d, 0x000ae>
Jurassic.Compiler.Binder.CreateDelegateCore (int) <IL 0x00062, 0x00183>
Jurassic.Compiler.Binder.CreateDelegate (int) <IL 0x0002f, 0x00101>
Jurassic.Compiler.Binder.Call (Jurassic.ScriptEngine,object,object[]) <IL 0x00004, 0x00031>
Jurassic.Library.ClrFunction.CallLateBound (object,object[]) <IL 0x00059, 0x001a6>
Jurassic.Library.FunctionInstance.CallWithStackTrace (string,string,int,object,object[]) <IL 0x00013, 0x00073>
(wrapper dynamic-method) Jurassic.Compiler.MethodGenerator.global_ (Jurassic.ScriptEngine,Jurassic.Compiler.Scope,object) <IL 0x0007c, 0x00554>
Jurassic.Compiler.GlobalMethodGenerator.Execute () <IL 0x00035, 0x00112>
Jurassic.CompiledScript.Execute () <IL 0x00006, 0x00028>
Jurassic.ScriptEngine.Execute (Jurassic.ScriptSource) <IL 0x00022, 0x00098>
Jurassic.ScriptEngine.Execute (string) <IL 0x00007, 0x00057>
JurassicStateMachine.Update () (at Assets/InterpretedScripting/JurassicStateMachine.cs:95)
Do you have any idea what would cause this?
Coordinator
Sep 8, 2014 at 1:22 AM
Edited Sep 8, 2014 at 1:25 AM
Yes, you are running on Mono, correct?

Mono doesn't support DynamicILInfo. See this bug report: https://bugzilla.novell.com/show_bug.cgi?id=677409

There is no official support for Mono, but there are a couple things you can try:
Sep 8, 2014 at 10:57 AM
I am running on Mono. A fairly out of date, somewhat non-standard build of Mono at that. Unity... /sigh...

I'll try those things today. Thank you.
Sep 9, 2014 at 6:19 PM
Defining Silverlight worked perfectly.

Precompiling scripts improves the performance of my original slow test case by literally 21000%, which is incredible. It improves the performance of my original fast test case by around 100%, which is also quite significant.

Compiling the slow test case takes 10.5ms. Executing it takes 0.05ms.

Compiling the fast test case takes 4ms, and executing it takes 3ms.

I think you've saved my project. Thank you so much!

(Do you have a donate link? I don't have much, but I'd like to contribute a little.)
Coordinator
Sep 10, 2014 at 1:16 PM
I'm glad it's working for you :-)

I don't have a donate link, sorry. If you are feeling generous, how about donating to your favourite charity? I'm sure they need the money more than I do.