From: Scott Sauyet on
On Jan 14, 3:01 pm, Jorge <jo...(a)jorgechamorro.com> wrote:
> On Jan 14, 7:17 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
>
>> So, has anyone got suggestions for improving these tests?
>
> Yes, :-)http://jorgechamorro.com/cljs/093/

Thanks. I'm confused, though. You don't seem to assign anything to
"library". Am I missing somthing? If not, then the test seems to be
meaningless.

> BTW, It's not faster i-- than i++.

No, I wouldn't expect it to be. But that doesn't imply that

for (i = bound; i--;) {/* ... */}

isn't faster than

for (i = 0; i < bound; i++) {/* ... */}

is, right? That's what Thomas was arguing.

-- Scott
From: Jorge on
On Jan 14, 10:01 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
> On Jan 14, 3:01 pm, Jorge <jo...(a)jorgechamorro.com> wrote:
>
> > On Jan 14, 7:17 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
>
> >> So, has anyone got suggestions for improving these tests?
>
> > Yes, :-)http://jorgechamorro.com/cljs/093/
>
> Thanks.  I'm confused, though.  You don't seem to assign anything to
> "library".  Am I missing somthing?  If not, then the test seems to be
> meaningless.

It's in the line #66: 2e5 elements.

(function (count) {
while (count--) {
library[count]= {img: 'img' + count + '.jpg', caption: 'Caption '
+ count};
}
})(window.JSLitmusMultiplier= 2e5);
--
Jorge.
From: Garrett Smith on
Thomas 'PointedEars' Lahn wrote:
> Scott Sauyet wrote:
>
>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> var photos = [], captions = [];
>>>>> for (var i = 0, len = library.length; i < len; i++) {
>>>>> photos.push(library[i]["img"]);
>>>>> captions.push(library[i]["caption"]);
>>>>> }
>>> var
>>> photos = [],
>>> captions = [],
>>> len = library.length;
>>>
>>> photos.length = captions.length = len;
>>>
>>> for (var i = len; i--;)
>>> {
>>> var o = library[i];
>>> photos[i] = o.img;
>>> captions[i] = o.caption;
>>> }
>> Any of the suggestions will work, of course.
>
> Alas, not all, as I have pointed out.
>
>> The differences have to do with readability versus performance.
>> Perhaps the most readable version would be something like this:
>>
>> var photos = [];
>> var captions = [];
>> for (var i = 0; i < library.length; i++) {
>> var element = library[i];
>> photos.push(element.img);
>> captions.push(element.caption);
>> }
>>
>> For people used to C-style languages, that loop will feel quite
>> familiar.
>
> You don't know what you are talking about. First of all, for all intents
> and purposes, ECMAScript is a C-style language. (If you have eyes to see
> you can observed the similarities.)
>
> (Therefore,) the backwards-counting loop will be familiar to "people used
> to C-style languages", and it will also be a lot more efficient than the
> one above.

You are making an assertion about observations you have made in
implementation-dependent, and of course, without proof.

After all there is no boolean type in C before C99, so you
> would use `int' (and guess what, C's `for' statement works the same as in
> ECMAScript save the implicit conversion!), and in C99 you would use
> `(_Bool) i--' for maximum efficiency.
>

I'm failing to see how the unavailability of boolean type in C is
relevant to the discussion of loop performance in ECMAScript.

Perhaps you can provide further information as to how this proves that a
backwards loop in ECMAScript is more efficient.

If `photos` order matters, then that ought to be a motivating factor for
which way to loop.

> The ascending order and the unnecessary push() calls will decrease
> efficiency considerably, and the push() call will decrease compatibility,
> too (JScript 5.0 does not have it).
>

The `push` method good for adding several elements at a time, as in:-

myArray.push(q,w,e,r,a,s,d,f,z,x,c,v);

That is not the case here. Calling `push` would be an extra function
call here. No need for it.

[...]
>
>> What Thomas suggests optimizes by reversing the iteration order. I
>> have heard that such a change often improves performance of JS loops,
>> but I don't know any numbers.
>
> Make benchmarks then,

Did you retest your benchmarks?

and you will see that the simple post-decrement
> increases efficiency considerably as well (else the pattern would not have
> prevailed, would it?). We have been over this ad nauseam before.
>

Any observed difference in performance will be implementation-dependent.

>> The main disadvantage for beginning programmers is that the loop is
>> somewhat less readable, at least until you get used to the convention.
>> It takes advantage of the fact that 0 in a test is read as false,
>> whereas positive integers are read as true.
>
> Do you get a kick out of explaining the obvious even though nobody has
> asked a question? And you are being imprecise after all: *All* numeric
> values *except* 0 (+0 and -0, but these are only Specification mechanisms)
> and NaN type-convert to `true'. We have discussed this numerous times as
> well.
>
>> One nice variation of this is this loop format:
>>
>> for (var i = library.length; i --> 0;) {
>> // ...
>> }
>>
>> This looks like "for i, starting at library.length, proceeding to 0,
>> do something". It really looks as though the code contains an arrow
>> ("-->"). In actuality this is the postfix decrement operator ("--")
>> followed by a greater-than compare (">"), and it takes advantage of
>> the fact that the comparison happens before the decrement.
>
> As in the more simple and more efficient i-- ...
>
>> But it's very pretty.
>
> Pretty according to whose standards? It could create misconceptions with
> newcomers about a limit-type `-->' operator, and it is even less readable
> or obvious than the versions you were incompetently whining about.
>
>> The OP will have to decide how to weight performance advantages
>> against code clarity, but in order to help, does anyone have links to
>> metrics on the different performance characteristics of loops in
>> different browser environments?
>
> The browser does not matter (the ECMAScript implementation does), and this
> discussion has been performed a hundred times or so already. So have
> results been posted. Much you have to learn.
>

It appears that you have believed some observations in a few browsers
and incorrectly come to the conclusion that a backwards loop is faster.

>
> Score adjusted
Nobody but you cares about your silly scorekeeping activities. They're
embarrassing. Best keep that to yourself and not tell anyone.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Jorge on
On Jan 14, 10:01 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
>
> No, I wouldn't expect it to be.  But that doesn't imply that
>
>     for (i = bound; i--;) {/* ... */}
>
> isn't faster than
>
>     for (i = 0; i < bound; i++) {/* ... */}
>
> is, right?

Yes but no. On a good day we would be talking at best about an
infinitesimal of a µs.

> That's what Thomas was arguing.

i<bound is a boolean, but i-- isn't, so what you've got to compare it
to is really ~ (i === 0) (i converted to a boolean). It might be true
that the test (i === 0) is some small fraction of a µs faster than
(i<bound), but for some reason (implementation ?) filling the arrays
upwards is faster than downwards and that weights much more than that
infinitesimal of µs in the end results.

The truth is that filling the arrays upwards is faster in most
browsers, and when not, they're ~ equally fast.

--
Jorge.
From: Scott Sauyet on
On Jan 14, 4:12 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
> Scott Sauyet wrote:
>> On Jan 14, 3:23 pm, Scott Sauyet <scott.sau...(a)gmail.com> wrote:
>> Updated version:
>>    http://scott.sauyet.com/Javascript/Test/LoopTimer/2/
>> Thanks again,
>
> There are too many variables in your test. The forwards loop body calls
> `push` twice, while the reverse loop does not.
>
> What is causing the performance difference? Is it the direction of the
> loop or is it the call to `push`? You can't tell from that test, can you?

I was trying really hard not to get sucked into the navel-gazing
arguments so prevalent here. So much for my New Year's resolution, I
guess. :-)

Thomas offered a suggested improvement to my function. My tests show
that for most reasonable cases it was an improvement, and also that
it's not as clear-cut as he suggested. I should have known better
than to distinguish one implementation from another on the basis of
one of their features (forward/backward), but I guess I'm stuck with
it now!

If I find some time tonight or tomorrow, I'll do a few more thorough
benchmarks of multiple versions of the algorithms and see what the
main issues are.

Thank you very much for your response.

-- Scott