Can't get Multithreaded Nashorn uses to Scale

Jesus Luzon jluzon at riotgames.com
Tue Dec 6 13:19:12 UTC 2016


Hey Jim,

I looked at it and I will look into loadWithNewGlobal to see what exactly
it does since it could be relevant. As for the rest, for my use case having
threads in the JS would not help. We're using Nashorn to build JSON filters
in a Dynamic Proxy Service and need any of the threads processing a request
to be able to execute the script to filter.

Also, when you say a new engine per threads is the worst case what exactly
do you mean? I would expect an initial cost of compiling the script on each
thread and then each engine should be able to do its own thing, but what
I'm seeing is that when running with more than 10 threads all my engines
get slow at executing code, even though they are all completely separate
from each other.

On Tue, Dec 6, 2016 at 5:07 AM, Jim Laskey (Oracle) <james.laskey at oracle.com
> wrote:

> Jesus,
>
> Probably the most informative information is in this blog.
>
> https://blogs.oracle.com/nashorn/entry/nashorn_multi_threading_and_mt
>
> This example uses Executors but threads would work as well.
>
> I did a talk that looked at different methods to max out multithreading
> performance.  A new engine per thread is the worst case.  A new context per
> thread does much better.  A new global per thread is the best while
> remaining thread safe.
>
> Cheers,
>
> — Jim
>
>
>
>
>
> On Dec 6, 2016, at 8:45 AM, Jesus Luzon <jluzon at riotgames.com> wrote:
>
> Hey folks,
>
> I've tried many different ways of using Nashorn multithreaded based on what
> I've found on the internet and I still can't get a single one to scale.
> Even the most naive method of making many script engines with my script
> tends to bottleneck itself when I have more than 10 threads invoking
> functions.
>
> I'm using the following code to compile my script and
> invocable.invokeFunction("transform", input) to execute:
>
>    static Invocable generateInvocable(String script) throws
> ScriptException {
>        ScriptEngineManager manager = new ScriptEngineManager();
>        ScriptEngine engine =
> manager.getEngineByName(JAVASCRIPT_ENGINE_NAME);
>        Compilable compilable = (Compilable) engine;
>        final CompiledScript compiled = compilable.compile(script);
>        compiled.eval();
>        return (Invocable) engine;
>    }
>
>
>
> The script I'm compiling is:
>
>        String script = "function transform(input) {" +
>                "var result = JSON.parse(input);" +
>                "response = {};\n" +
>                "for (var i = 0; i < result.length; i++) {\n" +
>                "    var summoner = {};\n" +
>                "    summoner.id = result[i].id;\n" +
>                "    summoner.name = result[i].name;\n" +
>                "    summoner.profileIconId = result[i].profileIconId;\n" +
>                "    summoner.revisionDate = result[i].revisionDate;\n" +
>                "    summoner.summonerLevel = result[i].level;\n" +
>                "    response[summoner.id] = summoner;\n" +
>                "}\n" +
>                "result = response;" +
>                "return JSON.stringify(result);" +
>                "};";
>
>
>
> I've also tried other more scaleable ways to work with scripts
> concurrently, but given that this is the most naive method where everything
> is brand new and I still get slowness calling them concurrently I fear that
> maybe I'm overlooking something extremely basic on my code.
>
> Thanks.
> -Jesus Luzon
>
>
>


More information about the nashorn-dev mailing list