From: Lasse Reichstein Nielsen on
Jorge <jorge(a)jorgechamorro.com> writes:

> Of course. When you said "stupid micro-benmarks" this one came to my
> mind:
> http://groups.google.com/group/comp.lang.javascript/msg/84fd9cbba33b9edd

Well ... it isn't doing very good at testing Javascript performance :)

Running the JS code in my eval-box
(http://www.infimum.dk/HTML/javascript/jstest6.html) gives a result
of 0.8 MHz (Chrome 5.0.342.2) and 1.5 MHz (Opera 10.50) [1].
If I wrap the code in a a function and call it ("function foo(){...} foo();")
and make sure that n, v and t are local variables (notice the semicolon
after 20e6 isn't a comma), I get a result of 55.7 MHz and 81 MHz
respectively.

Yes, it's too short, but the bigger problem is that it runs as
top-level code and uses global variables. In a browser, that can mean
a XSS security check for every variable access (at worst) and it
disallows a lot of optimizations because the variables are global and
therefore can be changed from pretty much anywhere at any time.

/L
[1] Running code in the scope of an eval is slooooow!
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

From: Antony Scriven on
On Mar 7, 10:46 am, Lasse Reichstein Nielsen wrote:

> Antony Scriven <adscri...(a)gmail.com> writes:
> > On Mar 7, 12:08 am, Michael Haufe wrote:
>
> >  > On Mar 1, 10:39 am, Dr J R Stockton
> >  > <reply1...(a)merlyn.demon.co.uk> wrote:
> >  > This approach would assume that the implementation in
> >  > question doesn't optimize away the loop as a useless
> >  > construct.
>
> > How? It's incrementing a variable. --Antony
>
> If it's a local variable (and you *really* shouldn't use
> global variable in a loop, or write benchmark code that
> runs at top-level), and it's not read again afterwards,
> and it's possible to see that the loop always terminates,
> then it's a safe optimization to remove the entire loop.
>
> I.e.
>  function test() {
>    var x = 42;
>    for (var i = 0; i < 1000000; i++) { x = x * 2; }
>  }
>
> This entire function body can safely be optimized away.
> Whether a JavaScript engine does the necessary analyzis
> to determine that is another question, but it's
> a possible optimization.

Ah yes, thanks, I see Michael's point now. I was thinking in
more general terms when I wrote that. I imagine the analysis
is much harder to do when global variables or global objects
are involved.

> Quite a lot of stupid micro-benmarks can be entirely
> optimized away like this.

Indeed. Those sorts of benchmarks are entirely
unrepresentative of any production code I've seen, and are
a small part of the total cost of developing software. --Antony
From: Jorge on
On Mar 7, 4:21 pm, Lasse Reichstein Nielsen <lrn.unr...(a)gmail.com>
wrote:
> Jorge <jo...(a)jorgechamorro.com> writes:
> > Of course. When you said "stupid micro-benmarks" this one came to my
> > mind:
> >http://groups.google.com/group/comp.lang.javascript/msg/84fd9cbba33b9edd
>
> Well ... it isn't doing very good at testing Javascript performance :)
>
> Running the JS code in my eval-box
> (http://www.infimum.dk/HTML/javascript/jstest6.html) gives a result
> of 0.8 MHz (Chrome 5.0.342.2) and 1.5 MHz (Opera 10.50) [1].
> If I wrap the code in a a function and call it ("function foo(){...} foo();")
> and make sure that n, v and t are local variables (notice the semicolon
> after 20e6 isn't a comma), I get a result of 55.7 MHz and 81 MHz
> respectively.

83.7MHz... that's what FF3.6 gives on my Mac !! Bully. So at the very
least, we know now that JS can + and / and loop at nearly 2/3rds the
"speed of C" (in vacuum :-). That alone is good news, it seems to
me.

Any good idea about what piece of code -anything a bit more complex- I
should test ?, I don't know, e.g., prime numbers, to see what gives ?

> Yes, it's too short, but the bigger problem is that it runs as
> top-level code and uses global variables. In a browser, that can mean
> a XSS security check for every variable access (at worst) and it
> disallows a lot of optimizations

Yep you're absolutely right. In the v8 shell the speed jumped to 2x
faster, in the jsc shell 5.4x to 49MHz (from 9!), etc. You've had a
pretty good idea.

> because the variables are global and
> therefore can be changed from pretty much anywhere at any time.

"changed from pretty much anywhere at any time" ? JS has a single
execution thread... ¿?

(function test () {
var k= 20e6, n= k, v= 0, t= +new Date();

while (n) {
v+= n/2/n;
n--;
}

t= +new Date() -t;
(this.alert || this.print)([
(k/t/1e3).toFixed(1)+ " MHz",
t+" ms", v]);
})();

Thanks,
--
Jorge.
From: "Michael Haufe ("TNO")" on
On Mar 7, 1:40 pm, Jorge <jo...(a)jorgechamorro.com> wrote:

> 83.7MHz... that's what FF3.6 gives on my Mac !! Bully. So at the very
> least, we know now that JS can + and / and loop at nearly 2/3rds the
> "speed of C"  (in vacuum :-). That alone is good news, it seems to
> me.

I don't believe FF 3.6 compiles a trace through eval atm. So I expect
that is the speed of the interpreter.
From: Dr J R Stockton on
In comp.lang.javascript message <8ad81ac9-617f-4aef-bbd7-105824b7b817(a)g2
8g2000yqh.googlegroups.com>, Sat, 6 Mar 2010 16:08:24, "Michael Haufe
(\"TNO\")" <tno(a)thenewobjective.com> posted:
>On Mar 1, 10:39 am, Dr J R Stockton <reply1...(a)merlyn.demon.co.uk>
>wrote:
>
>> The time for an empty loop should be carefully measured and subtracted.
>
>This approach would assume that the implementation in question doesn't
>optimize away the loop as a useless construct.

To be careful, one should also measure the time for an absent loop. If
that is the same as for an empty loop, then one must include in all test
loops something which will not be optimised.

To select something which cannot be optimised, one must determine the
smartness of the optimiser.

A counting loop must use a control variable, overt or concealed. In a
language such as Pascal, that could be declared in a procedure
containing the timing tests, and an optimiser could easily see when an
empty loop could be optimised out.

But in JavaScript a loop controlled by J might be followed, after
intervening definitely-non-J statements, by something like
alert(window[prompt("What")]) // enter 'J' or not-'J'
and at loop time the system cannot possibly tell whether the loop-exit
value of J will be needed later.

So at least the optimiser will have to determine the exit value of J, or
to check for such statements later in the execution.

There's a good use (in theory) for 'eval' - its presence late in
code can set a lower bound to the optimiser's level of caution.


So, to ensure that a loop cannot be optimised away, count with J
normally but include in the loop one step of a Lehmer/Park–Miller PRNG.
That step is reasonably fast; and only a really clever and perverse
optimiser would be able to recognise the situation and predict the
result of J steps in order to remove a loop in safety.

Pause to update Demo 6 in the master copy of
<URL:http://www.merlyn.demon.co.uk/js-quick.htm>.

If I am not mistaken, none of the browsers on this PC optimises out a
simple empty loop of the form Q_ = K_ ; while (Q_--) { } .

--
(c) John Stockton, near London. *@merlyn.demon.co.uk/?.?.Stockton(a)physics.org
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Correct <= 4-line sig. separator as above, a line precisely "-- " (RFC5536/7)
Do not Mail News to me. Before a reply, quote with ">" or "> " (RFC5536/7)