Questions about 'new' : is this pattern legit?

T

Thomas 'PointedEars' Lahn

Lasse said:
That's not a given.

It's possible that four function calls take longer than creating an Array
and calling one function that loops over the array and extracts the
elements again (possible, but not given), but the latter also allocates
space for the array. If this happens often enough, the memory overhead
will also cause earlier garbage collection.

That argument is dubious and the tests have no meaning because the function
argument in chaining may be an Array or Object reference anyway.
Incidentally, that is what can be observed in current general-purpose
libraries that use chaining.

You are correct that cost is not merely measured in runtime spent.
However, you are ignoring here that for, say, ten registrations I would
need ten chained function calls, or only one function call with an Array
instance of length 10. There can be no doubt that the chaining grows more
inefficient than the alternatives with each registration. With 1000
registrations I would still need only one Array instance or 1000 items to
iterate over, instead of 1000 calls to be made.

I find it particularly dubious that you have not noticed that the length of
the effective prototype chain can be an important factor regarding
efficiency. setChained() is an instance method with a short effective
prototype chain, setProp() and setProps() are prototype methods with longer
ones. I also don't see you considering that the chaining approach needs at
least one Function object more than the non-chaining one in your example.
All in all, I don't think your argument or test holds water.


PointedEars
 
A

Antony Scriven

That argument is dubious and the tests have no meaning
because the function argument in chaining may be an Array
or Object reference anyway. Incidentally, that is what
can be observed in current general-purpose libraries that
use chaining.

You are correct that cost is not merely measured in
runtime spent. However, you are ignoring here that for,
say, ten registrations I would need ten chained function
calls, or only one function call with an Array instance
of length 10. There can be no doubt that the chaining
grows more inefficient than the alternatives with each
registration. With 1000 registrations I would still need
only one Array instance or 1000 items to iterate over,
instead of 1000 calls to be made.

And if, on average, the OP has only four registrations, what
then? For the OP's specific case, theorising is pointless.
I'm not saying you should entirely ignore performance
considerations, and I do find Lasse's tests interesting, but
optimisation should always be based on hard evidence,
specific to the application. And remember The First Rule of
Performance Optimisation: don't. --Antony
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
That argument is dubious and the tests have no meaning because the function
argument in chaining may be an Array or Object reference anyway.

That is irrelevant. If you create more objects, but do so in both
cases, then it will just reduce the impact of the difference, but not
eliminate it.
Incidentally, that is what can be observed in current general-purpose
libraries that use chaining.

I won't argue against that without knowing the quality of code of
those projects (but I'll wager a guess and assume that bad code
could be blamed for most of their performance characteristics).
You are correct that cost is not merely measured in runtime spent.

Any other cost, e.g., memory allocation, generally shows up in runtime
as well.
However, you are ignoring here that for, say, ten registrations I would
need ten chained function calls, or only one function call with an Array
instance of length 10.

This is not about chaining. Chaining may or may not cause an overhead
compared to directly calling, but chaining wasn't mentioned in the
point I'm arguing against.

And as to the number of calls/length of the array, I'm not ignoring
it. I show that for the case where the number is four, the point
("... will always be more expensive than ...") doesn't hold.
I believe it will hold for larger numbers too, and I'm willing to test
it.
There can be no doubt that the chaining grows more
inefficient than the alternatives with each registration. With 1000
registrations I would still need only one Array instance or 1000 items to
iterate over, instead of 1000 calls to be made.

The overhead of creating the array will be reduced compared to the case
with fewer calls, but the cost of populating the array won't, nor will
the cost of iterating over it and extracting the values again. Those
are expensive memory accesses, compared to stack allocated function
arguments.

But again, I'm willing to test it: Is there number of calls where
creating the array is faster. It's not obvious that there is, nor is
it obvious that there isn't.
I find it particularly dubious that you have not noticed that the length of
the effective prototype chain can be an important factor regarding
efficiency. setChained() is an instance method with a short effective
prototype chain, setProp() and setProps() are prototype methods with longer
ones.

That is a good point. While it's the natural implementation of each of
these strategies, it does give a natural difference in the time of a single
method call (a quick test shows the difference to be marginal in Opera
and Chrome, and quite significant in Firefox).
I also don't see you considering that the chaining approach needs at
least one Function object more than the non-chaining one in your example.

It needs one function per instance, which is significant.
However, my main point was not about chaining (which I'm not convinced
is a win compared to diret calls), but purely against the notion that
passing an array of arguments in one call is always faster than doing
multiple calls.
All in all, I don't think your argument or test holds water.

Which test would?

I tried making another one, ignoring chaining for now, since it's not
part of the point I'm trying to make:
http://www.infimum.dk/privat/testcallvsarray.html

There does seem to be a point where using a single call with an array
is faster than doing separate calls. For Opera it is around *2000*
calls[1]. I'm wagering that counts as a very rare use case.

So, the point is that:
"Several function calls will be always more expensive than just one
and the creation of an Array instance."
is wrong. For such an absolute statement, it might not be surprising that
there is a counter example. However, it seems that for *any* reasonable
number of calls, calling is faster than building an array of arguments
and passing them in one go - in most browsers [2].
After testing, it seems that it's only the case in very
very rare cases.

/L "Function calls aren't slow. 'nuff said"

[1] Firefox is weird: An Array of length 2000 is *slower* than one
of length 3000!
[2] Just checked Safari. It's actually slightly faster with the array.
 
R

Richard Cornford

To be fair, I think that code intended for other developers' use
should be well-documented.

Fair enough, you might not have to go to the code for - Cufon -,
instead you could go to the documentation (assuming it actually was
good enough).
So, in my opinion, your concern about the "nature/process of
the second and third function calls" is unwarranted, provided
that the function's return value (and usage too, given the
bizarre operation nick wants) is explained adequately.

My concern here is only with how much understanding can be derived
from the source code itself. For that it makes no real difference if
understanding is only available through reference to documentation or
only through reference to other source code, what is significant is
that the code above is not saying what it is doing when it could be.

If maintenance is where most software development resources are spent
(as is frequently attested) strategies that ease maintenance can be
disproportionately advantageous (over, say, strategies that easy
initial code entry/typing). Writing directly understandable (even self-
documenting) source code is one such strategy, particularly for the
top level code that employs pre-built APIs (and the like).

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,207
Latest member
HelenaCani

Latest Threads

Top