VK wrote:
Randy Webb wrote: He may have thought he needed to sort arrays but sometimes a
better solution involves using some other mechanism than what
is originally though.
Mmm... Sorting is possible only on objects supporting IComparable
interface. Such are *for example* Array or String.
Object object doesn't have IComparable interface so a sentence
like "you need objects to sort" is meaningless to my *humble*
mind.
Huh? Arrays and Objects are *not* the same thing. We keep
telling you that and you keep ignoring it.
Do you care for one more attempt? Because this topic was
discussed here:
<http://groups.google.com/group/comp....pt/browse_frm/
thread/039e84717c0978d9/188f8dd6f2af8fe7?hl=en#188f8dd6f2af8fe7>
and I got nothing but explanations how stupid am I and that
the Object or Array performance are the same.
That is not what was said, though given your record for misunderstanding
any explanations given to you I cannot be surprised by more evidence
that you do not (or will not) understand what is explained to you. It is
that seemingly wilful disregard for the efforts of others to improve
your understanding that is (IMO inevitably) turning the nature of the
responses you receive to your posts towards the exclusively negative.
After that actually I had to conduct my own research for the
best performance. Results are posted here.
You mean on this group? In the thread referenced about the most you said
on the subject was:-
<quote cite="news:11**********************@g49g2000cwa.go oglegroups.com"
Pre-declared Array object served with proper integer index values
gives me 6 sec time gain on my %windir%\temp\ directory (hundreds
of files and folders) in comparison with Hashtable and 3 sec over
mis-treated Array (used one time as hash, another time as array).
You may imagine what is even 3 sec for usability issue. To keep
this time gain though I have to stay with Array w/o temporary
transformations Array > Hash > Array.
</quote>
- by which you appear to mean that using - anArray[integer] - gave
you a 6 second performance gain over using - anObject[string] - and
a 3 second gain over using - anArray[string].
Actually skip on explanations -
Yet again, assertions without anything to support them, or allow others
to directly discredit them.
I'm too tired of this crap.
Answer the questions you are asked and you may see the resolution of the
subject.
Other code is based on the proper understanding of Object and
Array nature, my code is based on a broken implementation exploit
which is not guaranteed to be presented everywhere.
OP is free to choose whatever he wants.
In the past you have posted examples of you attempts to time javascript,
and demonstrated your rational in drawing conclusions form those tests.
And at the time it was pointed out that the individual tests included so
much beyond what you were making statements about, and differed in what
they included beyond the subject of you conclusions, that any
conclusions drawn from the results would be invalid. The testing
methodology you demonstrated was so poor as to be useless, invalidating
you conclusions as a consequence.
As you have reacted to the criticism of you methodology by refusing to
post any more examples of your testing methods it is impossible to judge
whether thy have changed, but it seems reasonable to conclude that they
have not and so any deductions you now assert are backed by unshown
tests must reasonably be dismissed as based on fundamentally flawed
data. You can only change that impression by demonstrating that you
methodology has improved; by posting the code that does demonstrate the
points you are trying to make.
Consider the problem we have here: The question is which formulation of
property accessor most rapidly resolves into the value of interest. We
don't actually need to attempt to work out how fast any particular
property accessor is, only their relative performance. So given, for
example, the following two functions:-
function compA(a, b){
var x = a[1];
var y = b[1];
return (x < y) - (x > y);
}
function compB(a, b){
var x = a['1'];
var y = b['1'];
return (x < y) - (x > y);
}
- the only difference between them is that one uses an integer to access
the properties of an object and the other uses a string. Apart from that
they are identical. Theoretically any overheads in executing one will be
identical to the overheads in executing the other (given the same
arguments) and the _difference_ between their performance should be
entirely attributable to the use of the different types of property
accessor.
Having narrowed the subject of the test down to just the feature of
interest it may be possible to draw conclusions about subject, all else
being equal. Unfortunately all else is not equal, for one thing we
cannot perform the test without the influence of background tasks on
multitasking operating systems. But still, lets give it a whirl and see
what happens.
The functions above are comparison functions for use with the
Array.prototype.sort method, as it is sorting arrays that is of interest
here. We will use them to sort arrays of objects and arrays of arrays,
where the objects being sorted have two named properties including the
one being referenced and the arrays have two elements (so the look-up
performance should not be that influenced by the size of the objects in
use). The pertinent property will be assigned a random number and the
random numbers in the objects in each array to be sorted will be in the
same order so that each array will be sorted in exactly the same way.
The number of calls to the comparison functions will be counted (which
will verify that all of the arrays are undergoing the same sorting
process) and the array will have 10000 elements so that the process
takes long enough to minimise the influence of the low resolution of
timers available to javascript. All of the difference measurements are
against a dot-notation property accessor accessing a named property. The
test page is:-
<html>
<head>
<title></title>
<script type="text/javascript">
var a1 = [];
var a2 = [];
var a3 = [];
var a4 = [];
var a5 = [];
var y = [];
var i = 10000;
for(var c = 0;c < i;++c){
y.push(Math.random());
}
for(var c = 0;c < i;++c){
a1.push({'0':'x','1':y[c]});
a2.push(a1[c]);
a3.push(['x', y[c]]);
a4.push(a3[c]);
a5.push({'0':'x',n:y[c]});
}
function compA(a, b){
var x = a[1];
var y = b[1];
++count;
return (x < y) - (x > y);
}
function compB(a, b){
var x = a['1'];
var y = b['1'];
++count;
return (x < y) - (x > y);
}
function compC(a, b){
var x = a.n;
var y = b.n;
++count;
return (x < y) - (x > y);
}
</script>
</head>
<body>
<script type="text/javascript">
var start, end, dur, base;
var count = 0;
document.write('<br>Array of '+i+' objects using obj.n:-<br>');
start = new Date().getTime();
c = a5.sort(compC);
end = new Date().getTime();
base = dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;
document.write('<br>Array of '+i+' arrays using ar[\'1\']:-<br>');
start = new Date().getTime();
c = a4.sort(compB);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;
document.write('<br>Array of '+i+' arrays using ar[1]:-<br>');
start = new Date().getTime();
c = a3.sort(compA);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;
document.write('<br>Array of '+i+' objects using obj[\'1\']:-<br>');
start = new Date().getTime();
c = a2.sort(compB);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;
document.write('<br>Array of '+i+' objects using obj[1]:-<br>');
start = new Date().getTime();
c = a1.sort(compA);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
</script>
</body>
</html>
As each comparison function performs two property accesses the count of
the number of calls to the comparison function is doubled in order to
calculate the difference in performance of the particular property
accessor type. Differences that are negative are worse performance than
dot-notation property accessor, and positive results are better
performance. All results are in milliseconds.
The notation - ar - is used to indicate that the subject of the property
accessor is an array and - obj - to indicate when it is an object. The
following are the results of running the page in IE 6, Mozilla 1.5 and
Opera 8.5 on a 500MHz PIII on the Windows 98 operating system:-
500MHz PIII Win 98
IE 6 Mozilla 1.6 Opera 8.5
obj.n ------ ------ ------
ar['1'] -0.0028256 -0.0001109 -0.0021326
ar[1] -0.0033992 -0.0002661 -0.0006042
obj['1'] -0.0035054 -0.0001109 -0.0019548
obj[1] -0.0038666 -0.0001330 -0.0013862
The result that would be predicted form a literal implementation of ECMA
262 would be that dot-notation would be fastest, and so all of the
numbers shown should be negative, and that accessing with a string
should be faster than accessing with an integer, with Array accessing
being slightly slower than Object accessing.
We find that all the numbers are negative, so dot-notation is the
fastest form of property accessor here. And with the exception of Opera
string access is coming up faster than integer access, but (again with
the exception of Opera) Array access appears fractionally faster than
Object access.
Baring in mind that a 500MHz CPU is slow by any current standard and you
would expect to see the measured performance differences in property
accessors getting smaller as CPU speeds increased, the differences
between bracket-notation performance on a single browser range from
0.0015284 (biggest, Opera) to 0.0001552 (smallest, Mozilla)
milliseconds. That is, form 1.5 to 0.15 _millionths_ of a second. That
means that if you want to account for a 6 second difference in outcome
by just changing property accessors you need to be doing between
4,000,000 and 40,000,000 property accessing operations (and more is the
CPU is faster). Notice that IE will sort an random array of 10,000
elements in about 250,000 calls to the comparison function, and very
considerably fewer for smaller arrays.
But now to the "all else being equal" part of the problem. If you want
to attribute performance differences between property accessors to the
javascript implementation, and make deductions from the results as to
the "true" nature of that implementation, you would have to demonstrate
that any differences were entirely attributable to the internal workings
of the implementation and could not be manifestations of other factors.
However, Switch OS and things come out very differently. Repeating the
tests on the same class of CPU; PIII, and the same versions of the same
browsers, but switching to Windows 2000 (and a slightly faster CPU out
of necessity) we get:-
800Mhz PIII Win 2000
IE 6 Mozilla 1.6 Opera 8.5
obj.n ------ ------ ------
ar['1'] -0.0007224 -0.0000200 -0.0008154
ar[1] -0.0110437 0.0000022 -0.0001028
obj['1'] -0.0048314 -0.0000222 -0.0007799
obj[1] -0.0115749 0.0000244 -0.0004254
Given the faster CPU (500Mhz to 800MHz) we would expect the timings to
be about two thirds of the originals, they are not. IE is all over the
place, with some values worse and others better, but at least the
relative positions remain the same; strings are better than numbers and
Array access faster than Object access. On Mozilla we have a total turn
around, number access figures have gone positive and are now better than
dot-notation, but the overall performance difference is much better than
could be accounted for by CPU speed alone. The relative positions of
Opera's results are much the same as the first set but again the
performance difference is greater than could be accounted for by the CPU
speed.
I would expect that if these tests were repeated on other combinations
of CPU and OS we would see different results again. I would anticipate
that Windows XP and a P4 potentially reverse the results across the
board. In the same way as speed testing string comparisons against
regular expressions favours string comparison on PIII Win 98 machines
and regular expressions on Win XP P4 machines. That was an unexpected
phenomenon but makes sense because P4s have hardware optimisation that
favours the sort of things that regular expressions (and video
decompression) need to do and the Windows XP operating system was
written with a knowledge of their potential. Which also explains why the
results above exceed the differences expected by the change of CPU
speed. Windows 98 was written before the PIII existed and cannot fully
exploit any hardware acceleration it provides, while Windows 2000 can
take advantage of its potential (but may not). Windows 2000 will not
exploit the P4's special features, while windows XP may.
The bottom line is that you can time things, and maybe see an obvious
performance benefit in a particular action over another (given testing
on a wide range of browser, CPU and OS combinations indicates that the
perceived benefit is manifest in all/sufficient, and not actually
harmful to some), but you cannot make deductions about the internal
details of javascript implementations from those measurements. You
cannot say that any observed difference is a result of how the
implementation alone is coded because you cannot separate the execution
of the implementation form the OS/CPU environment in which you execute
it, and that combination makes a difference.
On the other hand, this whole thing is a quest for performance in the
wrong place. The differences in the performance of property accessors
are a mater of nanoseconds, you have to be doing millions of them before
it is an issue. Specifically, if you assert that you are sorting arrays
of only "hundreds" of elements and changing the type of property
accessor used makes a difference as large as 6 seconds then the
algorithm you are using is catastrophically bad. It should be to that
that you should be looking to achieve better performance not splitting
hairs over property accessors.
Richard.