From: Garrett Smith on
Andrew Dupont wrote:
> On Feb 9, 12:40 am, David Mark <dmark.cins...(a)gmail.com> wrote:

[...]

> This newsgroup is a comedic wonder. Don't ever change, guys.
>
*PLONK*

Have a nice day, sucker.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Andrea Giammarchi on
On Feb 9, 8:49 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
> B.  PureDom is just a script and it is clearly not optimal.  Not only
> that, but the various test functions for each library are apples and
> oranges.  So don't look at those tests as magic either.

PureDOM is optimal and linear for what it does, perform tasks exactly
as they are described but I agree PureDOM should be better described
somewhere in TaskSpeed.

I will create a PureHack/PureCheat version so that games will be
basically over for whatever library and I wonder at that time who
would be interested in PureHack "chart column" anymore ... this is not
interesting to me, nobody needs to demonstrate a direct innerHTML is
faster than a function call with inside the same operation, we all
know this, and it's kinda obvious to me.

However, since devs expectation about PureDOM seems to be the fastest
hack ever, rather than a linear way to solve tasks as described, I
guess this column to compare should be there.

Regards
From: Richard Cornford on
On Feb 9, 9:00 pm, David Mark wrote:
> jdalton wrote:
>> Hi David,
>
> This is a newsgroup. And what are you replying to?
>
>> Heh,
>> You have it backwards (larger number is better),

So nothing like being consistent?

<snip>
>> smaller is worse, that means your methods executed slower
>> than anyone else.
>
> But, assuming your tests make sense, ...
<snip>

A reasonable question, given how botched the 'pure DOM' part of
TaskSpeed turned out to be.

Looking at those test pages I observe that each HTML page that gets
queried makes lots of referees to:-

<URL: http://davidmissedthemark.com/slickspeed/system/blank.gif >

- which all get HTTP 404 responses (with quite a sizable (50Kb) 404
page body). It seems unlikely that failing to find the images would
have much, if any, impact on the results of these test, but it would
be nice to see test set-up functioning correctly before anyone started
using it.

Each of the test pages differ in the 'JS library' that they import and
a single line of code that calls the querying method from that
library, as you would expect. The following is the dojo example of the
actual test function from:-

<URL: http://davidmissedthemark.com/slickspeed/system/dojo.html >

| <script type="text/javascript">
| var context = document;
|
| function getLength(elements){
| return typeof elements.length == 'function'
| ? elements.length()
| : elements.length;
| }
|
| function test(selector){
| try {
| var data, elements, start, end,
| i = 0, comps = 0, distance = 0,

I don't see why these variable declarations are here inside the - try
- block instead of being at the beginning of the function body, but
their location will make no practical difference.

| times = [],
| start = +new Date();

The above is the recording of the start time for this test.

| function once() {
| return dojo.query(selector, context);

This is the line that calls the "library's" selector, and the only
point of difference inside the test function between the different
libraries.

| }

But what is this apparent function declaration doing here (in this
location) at all? ECMAScript syntax rules do not accommodate a
function declaration inside a block, and would not accept the above as
a function expression because then you would have an
ExpressionStatement that started with the - function - keyword, which
is forbidden.

So the only thing that is going to allow the above to be acceptable in
this location is going to be the language implementation supporting a
syntax extension. Most of them do, but there are two distinct styles
of syntax extension that accommodate apparent function declarations in
Statement contexts. The first is the IE style, where the apparent
declaration is seen as a function declaration despite its context and
'hoisted' to the being of the function body, evaluated during variable
instantiation, and so will have no impact here. The second, on the
other hand, is the style of syntax extension that introduces the
concept of a FunctionStatement, which gets evaluated at runtime just
like any other statement. The problem with that is that we have
already recoded the start time, and now we are going to be timing the
act of creating a function object as the result of a
FunctionStatement, but only in environments that provide that
particular syntax extension.

There really never was any need for the - once - function to be
declared inside a Block, and sticking with the vanilla ECMAScript
syntax would have avoided a variation in the test process across
platforms.


| (selector);

And what is this doing here? Either it is doing nothing at all (which
is what ECMA 262 says it should do), in which case why is it here at
all, or it is perhaps some attempt to call the preceding function (as
if it was a function expression, by some syntax extension where
ExpressionStatements are allowed to start with the function keyword).

This could do with being explained/justified.


| elements = once();
|
| do {
| comps++;
| once();
| } while ((distance = +new Date() - start) < 200);

This is the main timing loop. The - once - function gets called once
in order to set - elements -, - comps - is incremented and - once -
called again (meaning it has now been called twice since the start of
the timing), and then the - while - expression is evaluated. This
evaluation of the - while - expression involves the creation of a new
Date object, so the rate of creation of date objects is significant
for the test.

I wonder why the unary plus operator is applied to the Date object, as
the subsequent subtraction operation would force type-conversion of
its operands to numeric, but that is more a little odd than
significant.

The most important thing in this expression is the number 200 at the
end of the expression. It means that if the time reported by the new
Date object is more than 200 milliseconds after the date reported by
the original (start) date object then the - while - loop will be
stopped. That is, this test will terminate as soon after 200
milliseconds as the performance of the query method plus the rate of
Date object creation will allow.

As I have said before; I would not trust timing results that did not
differ from each other by less then 200 milliseconds. Dates in
browsers are just not that precise in the worst cases. Having the
whole test take little more than 200 milliseconds is quite likely to
see the influence of background tasks on the computer combined with
timing inaccuracies render the results meaningless.

Now, suppose that after the first pass through the - do - loop body
the 200 milliseconds has elapsed; the - once - function has been
executed twice, and - comps - has been incremented to the numeric
value of 1. This means that - comp , - as a measure of how many
operations have been performed within the timed period, is 50% off the
correct number. This error is reduced as the number of operations
performed increases, but it does mean the test is going to exaggerate
its built in bias against the worst performing 'library'.

I wonder what the point of assigning the millisecond duration to the -
distance - variable is. When the - do - loop ends this value will
(minus the inaccuracies of javascript Date objects) contain the amount
of time taken for the number of operations actually performed (plus
any function creating resulting form FunctionStatement syntax
extensions, and a certain amount of Date object creation, etc.). So
this value, combined with the - comp - value (if it wasn't up to 50%
inaccurate) should be able to provide the important 'operations pre
millisecond' result of this test. But strangely - distance - is never
referenced again, and so assigning it a value here is just another
operation being timed in the loop.

| return {
| 'time': 0,
| 'found': getLength(elements),
| 'ops': comps / 100

Here (assuming no exceptions have been thrown) the result is returned.
But what is going on here; - comps -, which not quite the number of
operations performed, is divided by a seemingly very arbitrary 100?
The loop is constrained by a 200 millisecond value. The test process
must come in at over 200 milliseconds; dividing by 200 would still not
be the right thing to do, but dividing by 100 seems distinctly odd.

The values reported by these test are certainly not operations per
millisecond, by any reasonable measure of what operations pre
millisecond could mean.

| };
| }
| catch(e){
| if (elements == null)
| elements = { 'length': -1 };
| return {
| 'ops': 0,
| 'time': ((+new Date() - start) / (i || 1)) || 0,
| 'found': getLength(elements),
| 'error': (e.fileName || '?.js')
| .replace(/^.*(\/[^\/]+)$/, '$1') +
| '#' + e.lineNumber + ': ' + e.message
| };
| }
| };
|
| test.name = "dojo1.4.js?1264409293";
|
| </script>

I am afraid that as it stands these tests are a mess, and I would not
attribute any meaning to their results.

Richard.
From: jdalton on
Richard,

Thanks for the review. The tests were originally generated by PHP (I
am not the original author).
`(selector);` was part of that. If a custom method was defined it
would become `custom(selector)`.

I have made adjustments based on your review. The cost of `new Date`
is not really a concern because it is shared by all tests/libs.
The operations count for each is now higher, because more time is
allowed to pass, but the overall trend of MyLib being one of the
slowest (lowest number of executions per period of time) is unchanged.


IE8 (Compatibility Mode)
5,958 8,362 3,238 5,681* 17,768 8,630 3,499

Opera 9.25
7,675 13,137 4,688 6,599* 25,826 14,941 6,620

Opera 9.50
33,643 31,268 11,725 24,128* 71,395 36,086 27,150

Safari 3.0.4
2,715 2,561 2,333 2,325* 8,794 3,787 2,547
From: David Mark on
Andrea Giammarchi wrote:
> On Feb 9, 8:49 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
>> B. PureDom is just a script and it is clearly not optimal. Not only
>> that, but the various test functions for each library are apples and
>> oranges. So don't look at those tests as magic either.
>
> PureDOM is optimal and linear for what it does, perform tasks exactly
> as they are described but I agree PureDOM should be better described
> somewhere in TaskSpeed.

Well, that depends on your definition of "optimal".

>
> I will create a PureHack/PureCheat version so that games will be
> basically over for whatever library and I wonder at that time who
> would be interested in PureHack "chart column" anymore ... this is not
> interesting to me, nobody needs to demonstrate a direct innerHTML is
> faster than a function call with inside the same operation, we all
> know this, and it's kinda obvious to me.

You are really defensive. And what is it you plan to do that is "cheating?"

>
> However, since devs expectation about PureDOM seems to be the fastest
> hack ever, rather than a linear way to solve tasks as described, I
> guess this column to compare should be there.
>

Whatever. Is this a contest?