Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Use Rhino in HTTPServlet, poor performance

120 views
Skip to first unread message

DVD

unread,
Aug 29, 2009, 1:50:48 PM8/29/09
to dev-tech-js-...@lists.mozilla.org
Hello:

I intend to use Rhino in my HTTPServlet methods to execute a javascript
everytime user request a url. But according to doc, for every method call,
I have to first use Context.enter()/Scrope/ before eval the same static
script
again and again. This is to meet the requirement that Context must be
created
for each thread and due to servlet model, this incurs huge overhead for
performance,
particularly when many users hits the url at the same time. Is there a way
to have a precompiled form of the Javascript file created only once and
used
for multple thread? The script file itself can be assumed static and no
need for
implementing dynamic reload, which would make it easier.

Thanks very much

David Parks

unread,
Aug 29, 2009, 8:12:44 PM8/29/09
to dev-tech-js-...@lists.mozilla.org
How many worker threads do you have? Context.enter() isn't an expensive
operation assuming you have the context set up already for each thread. I've
executed upwards of 10,000 Context.enter/exit() operations a second
(including executing a small amount of JS and resuming+suspending the JS
execution) on a single processor (numbers are off the top of my head it was
a while ago that I profiled it, but in any case it was a large number). If
it's really a big problem for you (perhaps your threads are being destroyed
rather than recycled??), you might consider setting up a smaller Work Queue
(an executor service) of threads that process javascript and submitting
requests to process javascript to that smaller set of threads.

If this is a conceptual concern I suggest profiling the scenario to find out
what really happens in your situation.

Dave

Hello:

Thanks very much
_______________________________________________
dev-tech-js-engine-rhino mailing list
dev-tech-js-...@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

DVD

unread,
Aug 29, 2009, 10:35:13 PM8/29/09
to David Parks, dev-tech-js-...@lists.mozilla.org
Thanks. I have many threads come and go instead of a fixed pool so the
overhead is big.
I hope rhino to have a mode that would allow a preloaded/compiled JS
(template) to be executed repeatedly
with different scope (essentially a template engine ) to produce an
output string.
the template would run in only single thread before producing the output.
Equivalent of Freemarker engine. Would it be possible? Or because of
this issue,
Rhino has not been widely used as template engine for Java, compared to
others like
velocity/freemarker.

Thanks

Rapha

unread,
Aug 30, 2009, 7:50:27 AM8/30/09
to
Javascript files can be compiled to Java bytecode. Have a look here:

https://developer.mozilla.org/en/Rhino_JavaScript_Compiler

HTH,
Raphael

> > dev-tech-js-engine-rh...@lists.mozilla.org


> >https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>
> > _______________________________________________
> > dev-tech-js-engine-rhino mailing list

> > dev-tech-js-engine-rh...@lists.mozilla.org
> >https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>
>

Martin Blom

unread,
Aug 30, 2009, 8:38:47 AM8/30/09
to DVD, dev-tech-js-...@lists.mozilla.org
DVD wrote:
> Thanks. I have many threads come and go instead of a fixed pool so
> the overhead is big.
> I hope rhino to have a mode that would allow a preloaded/compiled JS
> (template) to be executed repeatedly
> with different scope (essentially a template engine ) to produce an
> output string.
> the template would run in only single thread before producing the output.
> Equivalent of Freemarker engine. Would it be possible? Or because of
> this issue,
> Rhino has not been widely used as template engine for Java, compared
> to others like
> velocity/freemarker.
This should definitely not be a problem.

In ESXX, for instance, I have an ExecutorService with a ThreadFactory
that enters/leaves a JS context as part of the thead's lifespan. These
threads then handles requests by calling functions in a JS application
scope. The application scope is set up once when the JS app is loaded,
by executing the pre-compiled JS scripts files (using
Context.compileString()) with it.

If you want your requests to execute isolated from each other, you can
simply create a new global scope and execute the compiled script with it
for each request.

(It's also possible to mix these strategies by having a shared top-level
scope and using the prototype chain to add per-request scopes (needs
Context.FEATURE_DYNAMIC_SCOPE, I think), but I could never quite get
this to work properly, since in ESXX, I need to allow arbitrary Java
threads to call JS functions, and there were some issues that I have
forgotten about now.)

--
---- Martin Blom --------------------------- mar...@blom.org ----
Eccl 1:18 http://martin.blom.org/

DVD

unread,
Aug 30, 2009, 10:11:53 AM8/30/09
to Martin Blom, dev-tech-js-...@lists.mozilla.org
What I would expect is Rhinoe would have a mode that allows the following
(it is ok to disable some features such as concurrentcy within JS to
make it happen)

public static context = Context.enter();
public static globalCompiledScript = context.compile(script)
public static globalScope = .....
(the above is done in main thread , not threadlocal, just done once
during program init)

then in each thread,
localScope = ..... (localscope backdropped by globalscope)
globalCompiledScript .exec(localscope)

Most other template engines work this way. would it be possible for Rhino?

Attila Szegedi

unread,
Aug 30, 2009, 12:28:23 PM8/30/09
to DVD, Martin Blom, dev-tech-js-...@lists.mozilla.org
What other template engines work this way? (I'm one of primary
developers of FreeMarker, and the concept doesn't strike me as
familiar there :-) )

Anyway, this too is possible. In one context (say, the one that also
compiles the script, although this is not strictly necessary):

globalScope = cx.initStandardObjects();

then in the repeated contexts (i.e. those handling HTTP requests),
just do:

ScriptablelocalScope = cx.newObject(globalScope);
localScope.setPrototype(globalScope);

although you will likely also need to create the contexts through a
context factory that returns true for
hasFeature(FEATURE_DYNAMIC_SCOPE) if you do that. Anyway, you can try
without that actually, but if you run into weird behaviour with
properties missing in the global scope. Also, be aware that now the
global scope became shared mutable state between threads. If your JS
scripts are good citizens, and don't do fancy stuff like redefine the
Array constructor or such (that is, treat the stuff in global scope as
immutable) then you'll be fine.

Attila.

DVD

unread,
Aug 30, 2009, 7:13:14 PM8/30/09
to Attila Szegedi, Martin Blom, dev-tech-js-...@lists.mozilla.org
Hi, there. I have been using freemarker :-). I'd like to clarify if I
could do the similar way to that of freemarker
in freemarker, I could do during program init (main thread)
class Main{

static Configuration cfg = new Configuration();
static cfg.setDirectoryForTemplateLoading(new File("dir"));

static Template temp = cfg.getTemplate("test.ftl");
}
then in any other methods (whatever thread it could be) just do
Map root = .... (fillup data model)
Main.temp.process(root,....)

I have not seen an example for rhino to do this way. The template would
only do normal template processing.
no fancy stuff. Can Rhino have a mode to do this way with thread safety
gurranteed.

Thanks very much.

Attila Szegedi

unread,
Aug 31, 2009, 4:25:13 AM8/31/09
to DVD, Martin Blom, dev-tech-js-...@lists.mozilla.org
Okay, there are several differences in the design of the two languages
that make it more difficult for Rhino to work that way:

1. FreeMarker language is designed so that the execution of the
template can't mutate the data you passed in. A template can define
new variables that are local to an individual "process()" call, but it
completely lacks language elements that would modify the passed-in
ones (redefining existing names will simply result in a new local that
"shadows" the original; much like JavaScript does with a prototype
scope + a top level thread local scope). JavaScript, being a generic
imperative programming language, doesn't live with this constraint per
se. Best you can do to lower the overhead is the use-shared-global-
scope-as-prototype approach that both Martin Blom and I mentioned,
although as we both said, it breaks the isolation of programs from one
another, but again, it shouldn't be much of a problem if your scripts
don't actually go rogue on those shared objects.

2. FreeMarker's runtime execution model does define a program loading
and caching mechanism, JavaScript doesn't have one, by design. In
JavaScript, it's up to the host environment to provide program
loading. Behind FreeMarker's "getTemplate()" call (and its [#include]
directive) there's a whole loading, compiling, and memory-sensitive
caching mechanism. Again, in JavaScript, and consequently Rhino, there
is no such thing. You can get something similar by using existing web
frameworks that support Rhino, or roll your own. However, in basic
case, just using Context.compileReader() and then repeatedly calling
exec() on the resulting Script object is all you need.

Lots of people use the shared global scope + precompiled scripts with
Rhino and are quite happy with the performance. If you implement these
measures, there's good chance you'll be happy too; if not, you'll have
to profile your system, identify actual bottlenecks, and then please
come back to us and we'll see what we can do. But first try shared
global scope + precompiled scripts.

Hope that helps.

Attila.

--
home: http://www.szegedi.org
twitter: http://twitter.com/szegedi
weblog: http://constc.blogspot.com

wolffiex

unread,
Aug 31, 2009, 2:08:24 PM8/31/09
to
On Aug 30, 4:50 am, Rapha <rspe...@gmail.com> wrote:
> Javascript files can be compiled to Java bytecode. Have a look here:
Or you can just call context.compileString/compileReader (right?)

A

DVD

unread,
Aug 31, 2009, 7:55:44 PM8/31/09
to Attila Szegedi, Martin Blom, dev-tech-js-...@lists.mozilla.org
Thanks for taking time explaining. My understanding is that I could do
public static compiledScript =Context.compileReader() in main thread
and compiledScript.exec() in any newly created threads after that as
long as
the script does not have any unusual usage, Is that correct?
The javadoc of Rhino always mentions Context has to be associated with
relevant threads,
which is why I ask this question.

Attila Szegedi wrote:
> Okay, there are several differences in the design of the two languages
> that make it more difficult for Rhino to work that way:
>
> 1. FreeMarker language is designed so that the execution of the
> template can't mutate the data you passed in. A template can define
> new variables that are local to an individual "process()" call, but it
> completely lacks language elements that would modify the passed-in
> ones (redefining existing names will simply result in a new local that
> "shadows" the original; much like JavaScript does with a prototype
> scope + a top level thread local scope). JavaScript, being a generic
> imperative programming language, doesn't live with this constraint per
> se. Best you can do to lower the overhead is the

> use-shared-global-scope-as-prototype approach that both Martin Blom

>>>>> DVD wrote:
>>>>>
>>>>>> Thanks. I have many threads come and go instead of a fixed pool so
>>>>>> the overhead is big.
>>>>>> I hope rhino to have a mode that would allow a preloaded/compiled JS
>>>>>> (template) to be executed repeatedly
>>>>>> with different scope (essentially a template engine ) to produce an
>>>>>> output string.
>>>>>> the template would run in only single thread before producing the
>>>>>> output.
>>>>>> Equivalent of Freemarker engine. Would it be possible? Or
>>>>>> because of
>>>>>> this issue,
>>>>>> Rhino has not been widely used as template engine for Java, compared
>>>>>> to others like
>>>>>> velocity/freemarker.
>>>>>>

>>>>> This should definitely not be a problem.
>>>>>
>>>>> In ESXX, for instance, I have an ExecutorService with a ThreadFactory
>>>>> that enters/leaves a JS context as part of the thead's lifespan.
>>>>> These
>>>>> threads then handles requests by calling functions in a JS
>>>>> application
>>>>> scope. The application scope is set up once when the JS app is
>>>>> loaded,
>>>>> by executing the pre-compiled JS scripts files (using
>>>>> Context.compileString()) with it.
>>>>>
>>>>> If you want your requests to execute isolated from each other, you
>>>>> can
>>>>> simply create a new global scope and execute the compiled script
>>>>> with it
>>>>> for each request.
>>>>>
>>>>> (It's also possible to mix these strategies by having a shared
>>>>> top-level
>>>>> scope and using the prototype chain to add per-request scopes (needs
>>>>> Context.FEATURE_DYNAMIC_SCOPE, I think), but I could never quite get
>>>>> this to work properly, since in ESXX, I need to allow arbitrary Java
>>>>> threads to call JS functions, and there were some issues that I have
>>>>> forgotten about now.)

Johan Compagner

unread,
Sep 1, 2009, 5:09:17 AM9/1/09
to dev-tech-js-...@lists.mozilla.org
Creating a Context so calling Context.enter() is really a very simple thing
to do
If it is the first call for that thread then it just creates an Context
object and set this one as a thread local var.
Its pretty much impossible that you can see that as a hotspot in your
profiler.

The only thing that i can see what could be slow if you have
ContextListeners and you do there heavy stuff..

DVD

unread,
Sep 13, 2009, 9:28:44 PM9/13/09
to Attila Szegedi, Martin Blom, dev-tech-js-...@lists.mozilla.org
Hello
,
Is there a comparision for pro and cons to use freemarker versus rhino
(with a template unitility class)
as general purpose template engine?
rhino is quite matured but I have seen few apps/webapps are using it as
template engine.
I have been using Freemarker but feel that using Rhino is much cleaner
and compact, of course,
only need to use Javascript in web dev instead of the extra freemarker
mini language.
But I wonder if there have been showstoppers, performance issue when
comparing these two choices.

Thanks

Attila Szegedi

unread,
Sep 14, 2009, 3:41:26 AM9/14/09
to DVD, rhino Dev
Well, you pretty much listed all pros and cons yourself. JavaScript is
a general-purpose programming language, and while quite malleable,
you'd still likely end up with a lot of syntactic cruft in your
"templates" (that is, programs whose main purpose is to render textual
output). You might have better luck by programmatically constructing
a DOM and having it rendered, maybe with some library that makes
constructing a DOM expressive.

That is, for this particular purpose (rendering textual output)
FreeMarker is likely more ergonomic than JavaScript, because it was
expressly designed for exactly that purpose. That is not to say that
if you apply yourself to the problem and write a JS library with the
goal of making text output generating in JS as ergonomic as possible,
you couldn't arrive at something nice. I'm sure you could. Question
is, do you want to / have the resources to do it.

That said, I don't see any showstoppers. I'd be curious to hear about
your results if you decide to go with Rhino.

Attila.

DVD

unread,
Sep 14, 2009, 9:34:48 AM9/14/09
to Attila Szegedi, rhino Dev
Thanks. I will try.

>>> passed-in ones (redefining existing names will simply result in a

>>>>>>>> preloaded/compiled JS

Bediako George

unread,
Sep 14, 2009, 10:05:13 AM9/14/09
to DVD, Attila Szegedi, rhino Dev
If you are looking for templating alternatives have a look at
StringTemplate. We have used StringTemplate as our templating engine in
Hannibal, out open source web developement suite that relies on Rhino to
support JavaScript handlers. Hannibal has a set of utilities that make
StringTemplate and Rhino work great together for web develop. You can copy
our approach, or even use Hannibal instead if it makes sense for whatever
you are trying to accomplish.

You can find StringTemplate at www.stringtemplate.org. Hannibal can be found
here: http://code.google.com/p/hannibalcodegenerator/

Regards,

Bediako

--
Bediako George
Partner - Lucid Technics, LLC
Think Clearly, Think Lucid
www.lucidtechnics.com
(p) 202.683.7486 (f) 703.563.6279

DVD

unread,
Sep 20, 2009, 4:24:46 PM9/20/09
to Bediako George, Attila Szegedi, rhino Dev
My goal is to have a single (mini) language for both backend template
and frontend authoring for Java
based web development. Javascript is ideal as the same javascript
developer can work on both
frontend and backend template instead of dealing with multiple ones.
StringTemplate is great but it does not allow rich frontend manipulation.

I feel javascript would be a perfect for this goal. But I have seen
almost no major package equivalent
of freemarker being done yet.


Bediako George wrote:
> If you are looking for templating alternatives have a look at
> StringTemplate. We have used StringTemplate as our templating engine
> in Hannibal, out open source web developement suite that relies
> on Rhino to support JavaScript handlers. Hannibal has a set of
> utilities that make StringTemplate and Rhino work great together for
> web develop. You can copy our approach, or even use Hannibal instead
> if it makes sense for whatever you are trying to accomplish.
>
> You can find StringTemplate at www.stringtemplate.org

> <http://www.stringtemplate.org/>. Hannibal can be found here:

> home: http://www.szegedi.org <http://www.szegedi.org/>

> <http://constc.blogspot.com/>

> <mailto:dev-tech-js-...@lists.mozilla.org>


> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>
>
> _______________________________________________
> dev-tech-js-engine-rhino mailing list
> dev-tech-js-...@lists.mozilla.org

> <mailto:dev-tech-js-...@lists.mozilla.org>


> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>
>
>
>
> --
> Bediako George
> Partner - Lucid Technics, LLC
> Think Clearly, Think Lucid

> www.lucidtechnics.com <http://www.lucidtechnics.com>
> (p) 202.683.7486 (f) 703.563.6279

0 new messages