473,407 Members | 2,315 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Object Hash vs. object Array preference

VK
Hello,
In my object I have getDirectory() method which returns 2-dimentional
array
(or an imitation of 2-dimentional array using two JavaScript objects
with auto-handled length property - please let's us do not go into an
"each dot over i" clarification discussion now - however you want to
call - you call it ;-)

array[0] contains records of all files in the current dir.
array[1] contains records of all subs in the current dir

Each records is in its turn is an array of 6 elements: file/folder
name, size, type, attributes, lastModified date, lastModified time.

Tking into account that someone will need to build a dialog interface
over this data IMHO array structure is the most suitable ('cause of
sorting issue).

Or a custom object on each directory entry still would be more
flexible? What would you personally prefer to get out of the functiuon
for easier programming?

Nov 11 '05 #1
38 5130
VK wrote:
In my object I have getDirectory() method which returns 2-dimentional
array
(or an imitation of 2-dimentional array using two JavaScript objects
with auto-handled length property - please let's us do not go into an
"each dot over i" clarification discussion now - however you want to
call - you call it ;-)
I can accept the term "2-dimensional array" for brevity, provided that
each element has the same number of subelements.
array[0] contains records of all files in the current dir.
array[1] contains records of all subs in the current dir

Each records is in its turn is an array of 6 elements: file/folder
name, size, type, attributes, lastModified date, lastModified time.

Tking into account that someone will need to build a dialog interface
over this data IMHO array structure is the most suitable ('cause of
sorting issue).
I don't understand this argument. What has sorting to do with it?
Or a custom object on each directory entry still would be more
flexible? What would you personally prefer to get out of the functiuon
for easier programming?


I'd prefer an Object-based object here since it is more difficult to
remember the index of the array element than the meaningful identifier
of the property. If needed later, an Array object can be extended to
a collection so that both access methods can be used.
PointedEars
Nov 11 '05 #2
VK
> > VK wrote:
Tking into account that someone will need to build a dialog interface
over this data IMHO array structure is the most suitable ('cause of
sorting issue).
.. Thomas 'PointedEars' Lahn wrote:
I don't understand this argument. What has sorting to do with it?
I meant to say that you cannot sort hash keys (object properties,
collection items - the Legion is its name) but you can sort arrays.
Need to admit though that in case like
record[e1, e2, e3, e4, e5] > sort all records by e4
I'm pretty cloudy about the best accepted mechanics and therefore I'm
not sure what to serve better: an Object or an Array. I used to handle
such issues on server-side through mySQL where the boring part is done
automatically on the background.
.. Thomas 'PointedEars' Lahn wrote:
I'd prefer an Object-based object here since it is more difficult to
remember the index of the array element than the meaningful identifier
of the property. If needed later, an Array object can be extended to
a collection so that both access methods can be used.

That's not so much a question of usability but a question of
productivity.
Firstly the served object will be used for LOOKUP operations
exclusively (you cannot delete files/properties or add new ones here).
Secondly it will be used for LOOKUP operations very intensively. On a
big directory (over 100 files) display/sorting/selection will take
thousands of lookups so even 1ms difference will add up easily. I guess
it brings up the old question: is there any productivity difference
between Object and Array for lookup operations?

Nov 23 '05 #3
"VK" <sc**********@yahoo.com> writes:
I meant to say that you cannot sort hash keys (object properties,
collection items - the Legion is its name) but you can sort arrays.
Sorting implies ordering, which again implies indexability by counting
numbers, so yes, array elements can be sorted, rearranging their
property names. There is no ordering of general properties of objects,
so it's not even possible to define a notion of sorting on them.
Need to admit though that in case like
record[e1, e2, e3, e4, e5] > sort all records by e4
Not understood. If each record is a five element array, and you want
to sort it by its fourth element, then I'd do something like:
---
// generic comparison function
function cmp(a,b) {
return (b<a)-(a<b);
}

// creates function that compares property prop of arguments.
function cmpProperty(prop) {
return function (a,b) {
return cmp(a[prop],b[prop]);
};
}

// sort records by fourth element.
records.sort(cmpProperty(3));
---
I'm pretty cloudy about the best accepted mechanics and therefore I'm
not sure what to serve better: an Object or an Array.
Doesn't matter. You compare a property of the object, whether it's
called "3" or "foo" is irrelevant. So if you use the record anywhere
else, use meaningful names.

I guess it brings up the old question: is there any productivity
difference between Object and Array for lookup operations?


That depends on the implementation of Javascript it is running on.

A quick test:
---
function timeLookup(obj,prop, N) {
var t0 = new Date();
var x;
while(N--) {
x = obj[prop];
}
var t1 = new Date();
return t1-t0;
}

var N = 1000000;
var a = ["lal","lal","lala","lalala","lalalaalla"];
var t0 = timeLookup(a,"3", N);
var t1 = timeLookup(a,3, N);

var o = {"diller":"lal","daller":"lal","y":"lala","3":"lal ala",
"anguish":"lalalaalla"};
var t2 = timeLookup(o, "3", N);

var o2 = {"diller":"lal","daller":"lal","y":"lala","x":"lal ala",
"anguish":"lalalaalla"};
var t3 = timeLookup(o2, "x", N);

var o3 = {"diller":"lal","daller":"lal","y":"lala",
"dallerdallerdaller":"lalala","anguish":"lalalaall a"};
var t4 = timeLookup(o3, "dallerdallerdaller", N);

[t0,t1,t2,t3,t4]
---
gives the following results (times in ms):
array["3"] array[3] object["3"] object["x"] object["daller...."]
Opera 922 766 906 797 843
IE 6 906 891 891 937 1093
FF 746 406 750 625 906

So, of these, only Firefox seems to have a significantly more
efficient array lookup than property lookup, but longer property
names makes for longer lookup times.

It should probably also be tested on objects/arrays with lots
of properties, not just five.

Both Opera and Firefox seems to take extra time when the property is a
string containing a number literal, even when used on an object, not
an array. One can wonder why :)

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #4
VK
Lasse Reichstein Nielsen wrote:
If each record is a five element array, and you want
to sort it by its fourth element, then I'd do something like:
---
// generic comparison function
function cmp(a,b) {
return (b<a)-(a<b);
}

// creates function that compares property prop of arguments.
function cmpProperty(prop) {
return function (a,b) {
return cmp(a[prop],b[prop]);
};
}

// sort records by fourth element.
records.sort(cmpProperty(3));
Rather elegant but requires Object<>Array back and forth casting which
will swallow any productivity difference advantages between of them ?
A quick test:
---
function timeLookup(obj,prop, N) {
var t0 = new Date();
var x;
while(N--) {
x = obj[prop];
}
var t1 = new Date();
return t1-t0;
}

var N = 1000000;
var a = ["lal","lal","lala","lalala","lalalaalla"];
var t0 = timeLookup(a,"3", N);
var t1 = timeLookup(a,3, N);

var o = {"diller":"lal","daller":"lal","y":"lala","3":"lal ala",
"anguish":"lalalaalla"};
var t2 = timeLookup(o, "3", N);

var o2 = {"diller":"lal","daller":"lal","y":"lala","x":"lal ala",
"anguish":"lalalaalla"};
var t3 = timeLookup(o2, "x", N);

var o3 = {"diller":"lal","daller":"lal","y":"lala",
"dallerdallerdaller":"lalala","anguish":"lalalaall a"};
var t4 = timeLookup(o3, "dallerdallerdaller", N);

[t0,t1,t2,t3,t4]
---
gives the following results (times in ms):
array["3"] array[3] object["3"] object["x"] object["daller...."]
Opera 922 766 906 797 843
IE 6 906 891 891 937 1093
FF 746 406 750 625 906

So, of these, only Firefox seems to have a significantly more
efficient array lookup than property lookup, but longer property
names makes for longer lookup times.
Wow: double speed gain on Array with FF. These are 1-10 seconds speed
gain for application I guess - if you manage to stay within Array only.
IE seems rather indifferent but still just a bit quicklier. So I'd
explore Array-only solutions first if any is possible.
It should probably also be tested on objects/arrays with lots
of properties, not just five.
That's not my case, but I'd welcome any volunteer ;-)
Both Opera and Firefox seems to take extra time when the property is a
string containing a number literal, even when used on an object, not
an array. One can wonder why :)


Was that a rhetorical question? :-)
Naturally arr["3"] takes longer because the system is trying to find
first CDATA-named property "1", fails on that and only then it gets
array element with index 3.

Nov 23 '05 #5
VK wrote:
Lasse Reichstein Nielsen wrote:
Both Opera and Firefox seems to take extra time when the property is a
string containing a number literal, even when used on an object, not
an array. One can wonder why :)


Was that a rhetorical question? :-)
Naturally arr["3"] takes longer because the system is trying to find
first CDATA-named property "1", fails on that and only then it gets
array element with index 3.


CDATA is a data type specified in SGML/XML and used in DTDs for markup
languages. We are talking about a programming language specification
and its implementation, particularly ECMAScript 3 [1], subsection 11.2.1.

Will you learn how to quote?
PointedEars
___________
[1] <http://www.mozilla.org/js/language/E262-3.pdf>
Nov 23 '05 #6
VK
Thomas 'PointedEars' Lahn wrote:
CDATA is a data type specified in SGML/XML and used in DTDs for markup
languages. We are talking about a programming language specification
and its implementation, particularly ECMAScript 3 [1], subsection 11.2.1.
?

JavaScript/JScript Object accepts CDATA literals as property name.

Array index is unsigned 32 bit value which allows you to hold
4294967295 array elements per array-that's one less than 32 bits can
hold: the remaining one is used for the length value.

So in case:
someObject["3"] = "foo";
interpreter checks first if the key can be converted into an integer in
the range 0,..., 4294967295
If it can then someObject is treated as array (if contextually
possible) and its element with index 3 gets value "foo".

If the key cannot be converted into integer or if such integer goes
outside of the 0,..., 4294967295 range then the value is used as new
property name:
someObject["-1.5"] = "foo"; // creates key "-1.5" with value "foo"
someObject["4294967296"] = "foo"; // creates key "4294967296" with
value "foo"

By explicetly serving a valid index value to a pre-declared array:
someArray[3] = "foo";
you free the interpreter from the unnecessary checks/transformations
and you get a noticeable productivity gain.

In this concern I don't care too much (actually I don't care at all) if
ECMA specs are saying something other, because this is how it does
really work on any browser I know of.
Will you learn how to quote?


Well, sorry but I used to quote in the way one can see who am I
answering to (if there are several responses) and what am I answering
to:
Poster Name / Nickname wrote:
Quote
My answer
....
and I don't see any reason to change this habit unless some really
serious *logical* reasons will be provided (to fix it right away:
written rules are not one of them ;-)

Nov 23 '05 #7
"VK" <sc**********@yahoo.com> writes:
Rather elegant but requires Object<>Array back and forth casting which
will swallow any productivity difference advantages between of them ?
There is no casting anywhere. In Javascript, arrays *are* objects, and
their numbered properties are just that: object properties. The only
"magic" in arrays are in the internal [[put]] method, which keeps
the "length" property in sync with the numbered properties. A literal
implementation of the ECMAScript specification of objects would use
the same [[get]] method for arrays and non-array objects.
Wow: double speed gain on Array with FF. These are 1-10 seconds speed
gain for application I guess - if you manage to stay within Array only.
Only if the application does nothing but array accesses and takes 2-20
seconds to run.
IE seems rather indifferent but still just a bit quicklier.


That small a difference could easily be within the measuring
uncertainty.
Both Opera and Firefox seems to take extra time when the property is a
string containing a number literal, even when used on an object, not
an array. One can wonder why :)


Was that a rhetorical question? :-)
Naturally arr["3"] takes longer because the system is trying to find
first CDATA-named property "1", fails on that and only then it gets
array element with index 3.


That makes no sense. "CDATA" is an HTML type, not something that
exists in Javascript. If you just mean "string", then it's still
an interesting result, since the ECMAScript standard describes all
properties as strings, even array properties. The curious part was
that even on a non-array object, useing "3" as property name takes
longer than using "x", even though there is no reason to treat
numerals different from other property names.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #8
VK wrote:

[Quotation corrected]
Thomas 'PointedEars' Lahn wrote:
CDATA is a data type specified in SGML/XML and used in DTDs for markup
languages. We are talking about a programming language specification
and its implementation, particularly ECMAScript 3 [1], subsection 11.2.1.
?

JavaScript/JScript Object accepts CDATA literals as property name.


Sorry, but this *is* utter nonsense indeed. You obviously have no idea
what CDATA is. Hint: there is not one reference to it in the ECMAScript
Specification, or any _JS language_ reference for that matter.

We are talking about built-in language objects here, not host DOM
objects where a reference to the CDATA type might be appropriate.
Array index is unsigned 32 bit value
Yes.
which allows you to hold 4294967295 array elements per array- that's one
less than 32 bits can hold: the remaining one is used for the length
value.
With this description, I am not sure we understand each other as it was
meant.

32 bits allow you to store 4294967296 different unsigned states. That is
4294967295 non-zero states plus the zero state. Which is why you could
_theoretically_ hold 4294967296 elements in one Array, where the minimum
element index is 0 and the maximum one is 4294967295. However, since
there has to be a _separate_ `length' property that also can only hold
an unsigned 32-bit integer (range from 0 to 2^32-1 = 4294967295) at the
maximum as well, only 4294967295 elements are allowed and thus only
4294967294 is allowed for maximum index.
By explicetly serving a valid index value to a pre-declared array:
someArray[3] = "foo";
you free the interpreter from the unnecessary checks/transformations
No.

,-<http://www.mozilla.org/js/language/E262-3.pdf>
|
| [...]
| 11.2 Left-Hand-Side Expressions
|
| Syntax
|
| MemberExpression :
| PrimaryExpression
| FunctionExpression
| MemberExpression [ Expression ]
| MemberExpression . Identifier
| new MemberExpression Arguments
|
| [...]
| The production MemberExpression : MemberExpression [ Expression ] is
| evaluated as follows:
|
| 1. Evaluate MemberExpression.
| 2. Call GetValue(Result(1)).
| 3. Evaluate Expression.
| 4. Call GetValue(Result(3)).
| 5. Call ToObject(Result(2)).
| 6. Call ToString(Result(4)).
^^^^^^^^^^^^^^^^^^^^^^^^
| 7. Return a value of type Reference whose base object is Result(5) and
| whose property name is Result(6).

As you can see, if the implementation is standards compliant, all parameters
of the bracket property accessor are converted to String first. And *then*
follows

| 15.4 Array Objects
|
| Array objects give special treatment to a certain class of property names.
| A property name P (in the form of a string value) is an array index if and
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
| to 2^32?1.

So in terms of "saving the 'interpreter' work" it would be even more
efficient to always quote all parameters for the bracket property
accessor, thus saving it from type conversion in the abstract internal
ToString operator which is defined as follows:

| 9.8 ToString
|
| The operator ToString converts its argument to a value of type
| String according to the following table:
|
| Input Type Result
| ------------------------------------------------------------------
| Undefined "undefined"
| Null "null"
| Boolean If the argument is true, then the result is "true".
| If the argument is false, then the result is "false".
| Number See note below.
| String Return the input argument (no conversion)
| Object Apply the following steps:
| Call ToPrimitive(input argument, hint String).
| Call ToString(Result(1)).
| Return Result(2).
|
| 9.8.1 ToString Applied to the Number Type
|
| [too much to be quoted here, go read on that yourself]

You have not bothered to read the section of the specification I have
referred to and the other sections it is referring to. Again.
and you get a noticeable productivity gain.


The reasons for this lie elsewhere, it is perhaps due to a not conforming
implementation.
Will you learn how to quote?


Well, sorry but I used to quote in the way one can see who am I
answering to (if there are several responses) and what am I answering
to:
Poster Name / Nickname wrote:
Quote
My answer
...
and I don't see any reason to change this habit unless some really
serious *logical* reasons will be provided (to fix it right away:
written rules are not one of them ;-)


Your quotes are like this:

| > > User 1 wrote:
| > > [Text of User 1]
| .
| > User 2 wrote:
| > [Text of User 2]
|
| Your text

Expected (and, it appears to me, accepted) is:

| User 2 wrote:
| > User 1 wrote:
| > > [Text of User 1]
| >
| > [Text of User 2]
|
| Your text

Not only that the initial attribution line is to indicate who wrote what, to
allow quotes to be trimmed easily, the quotation character sequence is to
indicate the quotation level, to be able to assign quoted text to a person
easily.
HTH

PointedEars
Nov 23 '05 #9
Lasse Reichstein Nielsen wrote:
"VK" <sc**********@yahoo.com> writes:
Naturally arr["3"] takes longer because the system is trying to find
first CDATA-named property "1", fails on that and only then it gets
array element with index 3.


That makes no sense. "CDATA" is an HTML type, not
something that exists in Javascript.


Just to have my daily nitpick: it is an _SGML_ type :)
SCNR
PointedEars
Nov 23 '05 #10
"VK" <sc**********@yahoo.com> writes:
JavaScript/JScript Object accepts CDATA literals as property name.
No, that's confuzing terms. CDATA is a type in HTML documents. In the
DOM, the contents of CDATA sections and attributes are available as
Javascript strings. Objects accept *strings* as property names.

It might be a little pedantic, but its still correct :)
Array index is unsigned 32 bit value which allows you to hold
4294967295 array elements per array-that's one less than 32 bits can
hold: the remaining one is used for the length value.
Yes. (It's not that the last property is used to hold the length
property, as this could be misunderstood to say, just that the length
must be a 32 bit unsigned number and must be able to be one larger
than the largest used array index).
So in case:
someObject["3"] = "foo";
interpreter checks first if the key can be converted into an integer in
the range 0,..., 4294967295
It shouldn't (or needen't) do that according to the ECMAScript
specification. The expressions
someObject["3"]
and
someObject["03"]
access different properties. If someObject is an array, only the first
corresponds to an array element, so "can be converted into an integer"
is imprecise. A more precise way of saying it would be:
if the key is the canonical representation of an unsigned integer
in the range 0 .. 2^32-2...
If it can then someObject is treated as array (if contextually
possible) and its element with index 3 gets value "foo".
There is no "treating like an array". All properties are equal on
objects, arrays or not. Non-array objects are not "treated like
objects" if you use "3" as a property name, an array-objects
are not "treated like" objects when you use "x" - they *are*
objects.

Only when assigning to properties on an array is there a difference,
and only when assigning to a property name that is the canonical form
of an array index or is "length".
If the key cannot be converted into integer or if such integer goes
outside of the 0,..., 4294967295 range then the value is used as new
property name:
someObject["-1.5"] = "foo"; // creates key "-1.5" with value "foo"
someObject["4294967296"] = "foo"; // creates key "4294967296" with
value "foo"
And
someObject["123"] = "foo" // creates key "123" with value "foo"
// *and* if someObject is an array with
// someObject["length"] <= 123, it updates
// someObject["length"] to 124.
By explicetly serving a valid index value to a pre-declared array:
someArray[3] = "foo";
you free the interpreter from the unnecessary checks/transformations
and you get a noticeable productivity gain.
That is a possible optimization an implementation can do. You can keep
"array index" named properties as numbers and not convert the operand
to a string before doing the lookup. It seems most browsers does something
of this sort, even on non-arrays, which accounts for the larger overhead
when using the string "3" as operand of the property access operation.
In this concern I don't care too much (actually I don't care at all) if
ECMA specs are saying something other, because this is how it does
really work on any browser I know of.


Do you have documentation of that? Which browsers do you know of?

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #11
Lasse Reichstein Nielsen wrote:
"VK" <sc**********@yahoo.com> writes:
If it can then someObject is treated as array (if contextually
possible) and its element with index 3 gets value "foo".
There is no "treating like an array".


Exactly.
All properties are equal on objects, arrays or not.
No, see <14*****************@PointedEars.de>.
[...]
Only when assigning to properties on an array is there a difference,
and only when assigning to a property name that is the canonical form
of an array index or is "length".


Certainly not.
By explicetly serving a valid index value to a pre-declared array:
someArray[3] = "foo";
you free the interpreter from the unnecessary checks/transformations
and you get a noticeable productivity gain.


That is a possible optimization an implementation can do. You can keep
"array index" named properties as numbers and not convert the operand
to a string before doing the lookup.


Where is this backed up by ECMAScript 3 as an allowed optimization for
a compliant implementation?
PointedEars
Nov 23 '05 #12
VK
> Lasse Reichstein Nielsen wrote:
There is no casting anywhere. In Javascript, arrays *are* objects, and
their numbered properties are just that: object properties. The only
"magic" in arrays are in the internal [[put]] method, which keeps
the "length" property in sync with the numbered properties. A literal
implementation of the ECMAScript specification of objects would use
the same [[get]] method for arrays and non-array objects.


Sorry but that's an urban legend greatly dispropaganded in the 3rd
edition of my <http://www.geocities.com/schools_ring/ArrayAndHash.html>
and it will be completely busted in the 4th one I'm hoping to finish
before Christmas. To facilitate the cultural shock some people may
experience :-) here a piece of tast cases directly related to the
current OP. You are welcome to put each position into your own
benchmark test.
All comments are inside.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Template</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">

<script type="text/javascript">

var obj = {};
var arr = [];

function init() {
}

function test() {

/**
* Each block below should be uncommented
* separately before testing and commented
* back before moving to the next block
*/
/**
* Both Hashtable (used for Object) and Array
* accept non-ECMA naming compliant literals as property name:
*/
//obj["^^^CDATA^^^"] = "foo";
//arr["^^^CDATA^^^"] = "foo";
//alert(obj["^^^CDATA^^^"]); // "foo"
//alert(arr["^^^CDATA^^^"]); // "foo"
/**
* Array neither counts its properties
* as array elements nor it knows anything
* about them:
*/
//alert(arr.length); // 0

/**
* But Array's Object envelope
* knows about them:
*/
//alert("^^^CDATA^^^" in arr); // true
/**
* Array can hold up to 4294967295 indexed elements
* (which is 32 bit unsigned minus one bit for the length flag).
* This means that the maximum index you can use in array is
* 4294967294
*/
//arr[4294967294] = "foobar";
//alert(arr.length); // 4294967294

/**
* An integer bigger than 4294967294 or lesser than 0
* (so it cannot be used as an array index) turns on
* JavaScript Baby Care mechanics. Instead of simply break the
execution
* with "Invalid array index value" message as any other language would
do,
* interpreter switches the object from Array-mode to Hashtable-mode,
* converts argument from number to string and adds new key to the
hash.
* Naturally array doesn't know about it, exactly as Dr. Jekyll had
nothing
* but to guess what Mr. Hyde this time did.
* Also valuable cycles are being spent for all this marry-go-round.
*/
//arr[4294967294 + 1] = "foobar";
//alert(arr.length); // 0
//alert(4294967295 in arr) // true

/**
* The same as above happens if argument number but not an integer.
* Also valuable cycles are being spent for all this marry-go-round.
*/
//arr[1.5] = "bar";
//alert(arr.length); // 0
/**
* Serving a string index to array turns on
* JavaScript Baby Care mechanics also. First interpreter
* attempts to convert the string into valid index value.
* If it's possible: then the situation gets really ambigious:
* hell does user want to add "33" property or array[33] ?!?
* To cover all holes, interpreter both add new array element [33]
* and new property "33".
* Needless to say that a create amount of cycles goes for this
* thinking and arrangement.
*/
//arr["33"] = "foo";
//alert(arr.length); // 34
//alert("33" in arr) // true
/**
* If string value is not convertable into a valid array index,
* interpreter simply switches object from Array-mode to
* Object-mode and adds new property to the Object envelope.
* Still cycles are being vasted unless you really wanted to add
* new property to your array.
*/
arr["foo"] = "bar";
alert(arr.length); // 0
alert("foo" in arr) // true

/**
* These are all very basics above you need to understand
* clearly before to deal with code benchmarks: otherwise
* they will be one huge unresolved mistery to you.
* And naturally JavaScript Baby Care has absolutely nothing
* to do with Hashtable or Array nature, same way as its typeless
* has nothing to do with String or Number nature.
*/

}

function testIE() {
test();
}

function testFF() {
test();
}

window.onload = init;
</script>

<style type="text/css">
body {background-color: #FFFFFF}
var {font: normal 10pt Verdana, Geneva, sans-serif;
color: #0000FF; text-decoration: underline;
cursor: hand; cursor:pointer}
</style>

</head>

<body>

<noscript>
<p><font color="#FF0000"><b>JavaScript disabled:-</b><br>
<i><u>italized links</u></i> will not work properly</font></p>
</noscript>

<!--[if gte IE 5]>
<p>
<var onclick="testIE()">Test</var>
</p>
<![endif]-->
<![if ! gte IE 5]>
<p>
<var onclick="testFF()">Test</var>
</p>
<![endif]>

</body>
</html>

Nov 23 '05 #13
VK
Sorry for typo in the testcase I posted before (I had to extract parts
from a bigger sample).

Statements:

obj["^^^CDATA^^^"] = "foo";
arr["^^^CDATA^^^"] = "foo";

must be in the init() function and uncommented.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Template</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">

<script type="text/javascript">

var obj = {};
var arr = [];

function init() {
obj["^^^CDATA^^^"] = "foo";
arr["^^^CDATA^^^"] = "foo";
}

function test() {

/**
* Each block below should be uncommented
* separately before testing and commented
* back before moving to the next block
*/
/**
* Both Hashtable (used for Object) and Array
* accept CDATA literals as property name:
*/
//alert(obj["^^^CDATA^^^"]); // "foo"
//alert(arr["^^^CDATA^^^"]); // "foo"
/**
* Array neither counts its properties
* as array elements nor it knows anything
* about them:
*/
//alert(arr.length); // 0

/**
* But Array's Object envelope
* knows about them:
*/
//alert("^^^CDATA^^^" in arr); // true
/**
* Array can hold up to 4294967295 indexed elements
* (which is 32 bit unsigned minus one bit for the length flag).
* This means that the maximum index you can use in array is
* 4294967294
*/
//arr[4294967294] = "foobar";
//alert(arr.length); // 4294967294

/**
* An integer bigger than 4294967294 or lesser than 0
* (so it cannot be used as an array index) turns on
* JavaScript Baby Care mechanics. Instead of simply break the
execution
* with "Invalid array index value" message as any other language would
do,
* interpreter switches the object from Array-mode to Hashtable-mode,
* converts argument from number to string and adds new key to the
hash.
* Naturally array doesn't know about it, exactly as Dr. Jekyll had
nothing
* but to guess what Mr. Hyde this time did.
* Also valuable cycles are being spent for all this marry-go-round.
*/
//arr[4294967294 + 1] = "foobar";
//alert(arr.length); // 0
//alert(4294967295 in arr) // true

/**
* The same as above happens if argument number but not an integer.
* Also valuable cycles are being spent for all this marry-go-round.
*/
//arr[1.5] = "bar";
//alert(arr.length); // 0
/**
* Serving a string index to array turns on
* JavaScript Baby Care mechanics also. First interpreter
* attempts to convert the string into valid index value.
* If it's possible: then the situation gets really ambigious:
* hell does user want to add "33" property or array[33] ?!?
* To cover all holes, interpreter both add new array element [33]
* and new property "33".
* Needless to say that a create amount of cycles goes for this
* thinking and arrangement.
*/
//arr["33"] = "foo";
//alert(arr.length); // 34
//alert("33" in arr) // true
/**
* If string value is not convertable into a valid array index,
* interpreter simply switches object from Array-mode to
* Object-mode and adds new property to the Object envelope.
* Still cycles are being vasted unless you really wanted to add
* new property to your array.
*/
arr["foo"] = "bar";
alert(arr.length); // 0
alert("foo" in arr) // true

/**
* These are all very basics above you need to understand
* clearly before to deal with code benchmarks: otherwise
* they will be one huge unresolved mistery to you.
* And naturally JavaScript Baby Care has absolutely nothing
* to do with Hashtable or Array nature, same way as its typeless
* has nothing to do with String or Number nature.
*/

}

function testIE() {
test();
}

function testFF() {
test();
}

window.onload = init;
</script>

<style type="text/css">
body {background-color: #FFFFFF}
var {font: normal 10pt Verdana, Geneva, sans-serif;
color: #0000FF; text-decoration: underline;
cursor: hand; cursor:pointer}
</style>

</head>

<body>

<noscript>
<p><font color="#FF0000"><b>JavaScript disabled:-</b><br>
<i><u>italized links</u></i> will not work properly</font></p>
</noscript>

<!--[if gte IE 5]>
<p>
<var onclick="testIE()">Test</var>
</p>
<![endif]-->
<![if ! gte IE 5]>
<p>
<var onclick="testFF()">Test</var>
</p>
<![endif]>

</body>
</html>

Nov 23 '05 #14
VK
> Thomas 'PointedEars' Lahn wrote:
<http://www.mozilla.org/js/language/E262-3.pdf>
... and a bunch of quotes


To Thomas 'PointedEars' Lahn and to anyone who wants to prove its
position by quoting ECMA: this argument is not accepted unless proven
by test (like my position in the previous post is).

Otherwise you're in rather stupid position of a person who's meeting
the Magellan's ship arrival and who's quoting Aristot Earth model to
them to prove that their trip was absolutely impossible so it stays
impossible.

(Please - ECMA writing is not Aristot lore so I'm not a Magellan of any
kind, just a free associattion).

Nov 23 '05 #15
VK wrote:
Lasse Reichstein Nielsen wrote:
There is no casting anywhere. In Javascript, arrays *are*
objects, and their numbered properties are just that: object
properties. The only "magic" in arrays are in the internal
[[put]] method, which keeps the "length" property in sync
with the numbered properties. A literal implementation of
the ECMAScript specification of objects would use the same
[[get]] method for arrays and non-array objects.
Sorry but that's an urban legend


Which is an urban legend? That there is no casting? There is not. That
Arrays are Objects? They are. That the numbered properties of an array
are object properties? they are. That the only 'magic' is in the
internal [[Put]] method of an Array? Well the internal [[Put]] method is
a specification mechanism, it explains the behaviour it does not
constrain the implementation. Or that a literal implementation of
ECMAScript would use the same [[Get]] method? It would, but
implementations don't have to be literal, they just have to behave as if
they were literal.

People will find it much easier to correct your misconceptions if you
could clearly state what they are instead of making vague references to
wide ranging blocks of text.
greatly dispropaganded in the 3rd
edition of my
Without the ability to pin down and state what you are trying to
disprove it is unlikely that you will achieve anything, except spreading
more confusion and misconceptions.
<http://www.geocities.com/schools_ring/ArrayAndHash.html>
and it will be completely busted in the 4th one I'm hoping
to finish before Christmas. To facilitate the cultural shock
some people may experience :-) here a piece of tast cases
It would be better to present all of a test case rather than just a
piece of it as that may enable people to work out what it is exactly
that you are going on about this time.
directly related to the current OP. You are welcome to put
each position into your own benchmark test.
All comments are inside.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Template</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">

<script type="text/javascript">

var obj = {};
var arr = [];

function init() {
}

function test() {

/**
* Each block below should be uncommented
* separately before testing and commented
* back before moving to the next block
*/
/**
* Both Hashtable (used for Object) and Array
* accept non-ECMA naming compliant literals as property name:
ECMA 262 places no restrictions upon the character sequences used as
property names. The only restriction is that only property names that
correspond with the formal definition of an Identifier may be used with
dot notation property accessors. Bracket notation property accessors
have no such restrictions.
*/
//obj["^^^CDATA^^^"] = "foo";
//arr["^^^CDATA^^^"] = "foo";
//alert(obj["^^^CDATA^^^"]); // "foo"
//alert(arr["^^^CDATA^^^"]); // "foo"
100% in accordance with the behaviour specified in ECMA 262.
/**
* Array neither counts its properties
* as array elements nor it knows anything
* about them:
That is too incoherent to convey meaning.
*/
//alert(arr.length); // 0
100% in accordance with the behaviour specified in ECMA 262.
/**
* But Array's Object envelope
* knows about them:
What is an object "envelope"?
*/
//alert("^^^CDATA^^^" in arr); // true
100% in accordance with the behaviour specified in ECMA 262.
/**
* Array can hold up to 4294967295 indexed elements
* (which is 32 bit unsigned minus one bit for the
length flag).
What length 'flag'? do you mean the length property?
* This means that the maximum index you can use in array is
* 4294967294
*/
//arr[4294967294] = "foobar";
//alert(arr.length); // 4294967294
100% in accordance with the behaviour specified in ECMA 262.
/**
* An integer bigger than 4294967294 or lesser than 0
* (so it cannot be used as an array index) turns on
* JavaScript Baby Care mechanics.
Nothing is 'turned on', the behaviour is as specified and applies in all
cases.
Instead of simply break the execution
* with "Invalid array index value" message as any
other language would do,
Well they are not invalid array indexes they are _not_ array indexes so
they re treated as property names when used to add properties to an
object that is also an Array.
* interpreter switches the object from Array-mode to
Hashtable-mode,
Do you have any evidence for any switching? The specified behaviour is
that an Array is an object so it exhibits object behaviour when property
names do not qualify as array indexes.
* converts argument from number to string and adds new key
to the hash.
* Naturally array doesn't know about it, exactly as Dr. Jekyll
had nothing
* but to guess what Mr. Hyde this time did.
* Also valuable cycles are being spent for all this
marry-go-round.
*/
//arr[4294967294 + 1] = "foobar";
//alert(arr.length); // 0
100% in accordance with the behaviour specified in ECMA 262.
//alert(4294967295 in arr) // true
100% in accordance with the behaviour specified in ECMA 262. But I
thought you said that this array object did not know about properties
added with non-array index property names? This array object is
asserting that it has such a property.
/**
* The same as above happens if argument number but not an
integer.
* Also valuable cycles are being spent for all this
marry-go-round.
*/
//arr[1.5] = "bar";
//alert(arr.length); // 0
100% in accordance with the behaviour specified in ECMA 262.
/**
* Serving a string index to array turns on
* JavaScript Baby Care mechanics also.
Nothing is 'turned on' as the behaviour is inherent in the array object.
First interpreter
* attempts to convert the string into valid index value.
* If it's possible: then the situation gets really ambigious:
* hell does user want to add "33" property or array[33] ?!?
They are equivilent.
* To cover all holes, interpreter both add new array
element [33]
* and new property "33".
When they are both the same thing the interpreter cannot do 'both'. Only
one property is added to the object.
* Needless to say that a create amount of cycles goes
for this
* thinking and arrangement.
*/
//arr["33"] = "foo";
//alert(arr.length); // 34
//alert("33" in arr) // true
100% in accordance with the behaviour specified in ECMA 262.
/**
* If string value is not convertable into a valid array
index,
* interpreter simply switches object from Array-mode to
* Object-mode and adds new property to the Object envelope.
So that would be another assertion of 'switching' where none is evident
and 'envelopes' with no explanation or justification for the use of this
made-up term.
* Still cycles are being vasted unless you really wanted
to add
* new property to your array.
*/
arr["foo"] = "bar";
alert(arr.length); // 0
alert("foo" in arr) // true
100% in accordance with the behaviour specified in ECMA 262.
/**
* These are all very basics above you need to understand
* clearly before to deal with code benchmarks: otherwise
* they will be one huge unresolved mistery to you.

<snip>

What exactly is a sequence of demonstrations of arrays behaving in
accordance with the formal specification supposed to demonstrate?
Particularly, what it is supposed to demonstrate that suggests that
Lasse's comments are an urban legend?

All this does is suggest that you are still suffering form fundamental
misconceptions about the nature of javascript.

Richard.
Nov 23 '05 #16
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
All properties are equal on objects, arrays or not.
No, see <14*****************@PointedEars.de>.


That doesn't disagree with how I meant it to be understood :)

When a property (i.e., a name/value pair) has been created on an
object, it doesn't matter if it is on an array or a non-array
object. The [[Get]] method is the same in both cases, as is
[[HasProperty]] and [[Delete]], which are all you can do with the
existing property.
[...]
Only when assigning to properties on an array is there a difference,
and only when assigning to a property name that is the canonical form
of an array index or is "length".


Certainly not.


From section 8.6.2:

| For native objects the [[Get]], [[Put]], [[CanPut]],
| [[HasProperty]], [[Delete]] and [[DefaultValue]] methods behave as
| described in described in sections 8.6.2.1, 8.6.2.2, 8.6.2.3,
| 8.6.2.4, 8.6.2.5 and 8.6.2.6, respectively, except that Array
| objects have a slightly different implementation of the [[Put]]
| method (section 15.4.5.1).

Only the [[Put]] method on arrays makes arrays different from other
objects wrt. property access, and only when putting a value.

Reading the algorithms for [[Put]] on non-array objects and on array
objects, the array-version only acts differently if the property name
is "length" or if it is an array index (a numeral that is the
canonical form of an integer in the range 0 .. 2^32-2).

So, yes, all properties on objects are equal, arrays or not. The only
difference is what happens when you assign to a property of an array
with a name that is an array index or is "length".

Where is this backed up by ECMAScript 3 as an allowed optimization
for a compliant implementation?


That would be:

| 5.2 Algorithm Conventions
| The specification often uses a numbered list to specify steps in an
| algorithm. These algorithms are used to clarify semantics. In
| practice, there may be more efficient algorithms available to
| implement a given feature.

An implementation doesn't have to follow the algorithms from the
ECMAScript standard, it just has to give the same result. As such,
all semantics preserving optimizations are allowed.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #17
"VK" <sc**********@yahoo.com> writes:

[arrays are objects, their elements are object properties, only the
[[Put]] method on objects makes it differ from other objects ...
according to ECMAScript]
Sorry but that's an urban legend
It's what the ECMAScript standard specifies. It is all you can assume
about ECMAScript implementations in general. Specific implementations
might have certain characteristics that you can discover and use, e.g.,
an underlying implementation that is more or less efficient for numbers
than for strings. But it's not something you can rely on between
implementations.

.... var obj = {};
var arr = [];

....

All examples are consistent with ECMAScript, and what I said, so it is
only the timing of the implementation that can be discussed.

I agree that your description probably matches the internal model of
both IE, Mozilla and Opera's Javascript engines, to some extend.
There are differences between them that are probably also important.
If timing is really important, and has been shown to be so, not just
guessed at, I recommend fixing on a fe, browsers and testing
there, and then allowing the code to be slower on unknown or unexpected
browsers. Premature optimization is the root of all evil.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #18
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Lasse Reichstein Nielsen wrote:
All properties are equal on objects, arrays or not.


No, see <14*****************@PointedEars.de>.


That doesn't disagree with how I meant it to be understood :)

When a property (i.e., a name/value pair) has been created on an
object, it doesn't matter if it is on an array or a non-array
object. The [[Get]] method is the same in both cases, as is
[[HasProperty]] and [[Delete]], which are all you can do with the
existing property.


And how does the first paragraph of the Array object specification fit in?
There is clearly either replacing or additional property handling defined
for those objects, see below.
[...]
Only when assigning to properties on an array is there a difference,
and only when assigning to a property name that is the canonical form
of an array index or is "length".


Certainly not.


From section 8.6.2:

| For native objects the [[Get]], [[Put]], [[CanPut]],
| [[HasProperty]], [[Delete]] and [[DefaultValue]] methods behave as
| described in described in sections 8.6.2.1, 8.6.2.2, 8.6.2.3,
| 8.6.2.4, 8.6.2.5 and 8.6.2.6, respectively, except that Array
| objects have a slightly different implementation of the [[Put]]
| method (section 15.4.5.1).

Only the [[Put]] method on arrays makes arrays different from other
objects wrt. property access, and only when putting a value.
[...]


The specification seems to produce a contradiction by itself here.
In section 8.6.2 in restricts the difference to the [[Put]] method,
in section 15.4 it specifies "special treatment to a certain class
of property names."
Where is this backed up by ECMAScript 3 as an allowed optimization
for a compliant implementation?


That would be:

| 5.2 Algorithm Conventions
| The specification often uses a numbered list to specify steps in an
| algorithm. These algorithms are used to clarify semantics. In
| practice, there may be more efficient algorithms available to
| implement a given feature.

An implementation doesn't have to follow the algorithms from the
ECMAScript standard, it just has to give the same result. As such,
all semantics preserving optimizations are allowed.


ACK
PointedEars
Nov 23 '05 #19
VK
> Richard Cornford wrote:
100% in accordance with the behaviour specified in ECMA 262.


I'm not arguing with you any more. There are reasons to argue only if
the final aim is to find the true between each other arguments. It's a
vasted time if any fact is accepted if, and only if, it fits to the
books of canon.

Honnest the God I did not plan to make a trolling thread here - I
really wanted to find the most productive solution for my methods.
Unfortunately I have to conclude that I'm on my own in that as everyone
else is using wrong model, that gives totally wrong benchmark
predictions and totally wrong explanations (or no explanation at all)
to the benchmark results. That would be like asking someone who's using
flat model of Earth for an advise of the best way from Europe to China
through America.

"The great tragedy of science - the slaying of a beautiful hypothesis
by an ugly fact."
T.H. Huxley

Nov 23 '05 #20
VK wrote:
Richard Cornford wrote:
100% in accordance with the behaviour specified in ECMA 262.


I'm not arguing with you any more. There are reasons to argue only if
the final aim is to find the true between each other arguments. It's a
vasted time if any fact is accepted if, and only if, it fits to the
books of canon.


The language implementations you tested with are based on that canon,
more, they claim to be compliant to it. Any empirical proof you provide,
considering that the result is indeed unique (especially timing tests in
such short intervals are unreliable, taking caching, multitasking and other
factors to affect run-time into account) is perhaps valuable regarding a
specific version of a specific user agent on a specific computer, however
it does not bear meaning as a general test case and so it inappropriate
to refer to for general design decisions. Especially as you are merely
making unqualified assumptions what may or may not be without being able
to provide any proof for it, because we are dealing with Closed Source
except of Mozilla/5.0 based user agents.

You see, there are a whole lot of ifs here. Ignoring them in
your argumentation certainly do not make it a more convincing one.
HTH & HAND

PointedEars
Nov 23 '05 #21
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
And how does the first paragraph of the Array object specification fit in?
There is clearly either replacing or additional property handling defined
for those objects, see below. .... The specification seems to produce a contradiction by itself here.
In section 8.6.2 in restricts the difference to the [[Put]] method,
in section 15.4 it specifies "special treatment to a certain class
of property names."


No contradiction. There is special treatmet for a certain class of
property names (array indices and "length"). The special treatment
only occurs when you write to properties of those names, but it is
still special treatment.
For all other property names, the [[Put]] method on arrays works as
the [[Put]] method on non-array language objects.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #22
VK

Thomas 'PointedEars' Lahn wrote:
The language implementations you tested with are based on that canon,
more, they claim to be compliant to it. Any empirical proof you provide,
considering that the result is indeed unique (especially timing tests in
such short intervals are unreliable, taking caching, multitasking and other
factors to affect run-time into account) is perhaps valuable regarding a
specific version of a specific user agent on a specific computer, however
it does not bear meaning as a general test case and so it inappropriate
to refer to for general design decisions. Especially as you are merely
making unqualified assumptions what may or may not be without being able
to provide any proof for it, because we are dealing with Closed Source
except of Mozilla/5.0 based user agents.

You see, there are a whole lot of ifs here. Ignoring them in
your argumentation certainly do not make it a more convincing one.


I see... All empiric experiments are based on imperfect real world
systems so their results are not reliable in any given case. From the
other side ECMA specifications are based on pure mental compositions
without interception with the real world - therefore they are perfect
by their very nature and they don't need any further proof or
questionning. ECMA contains all knowledge and all answers - you just
need to open your sool to *believe* and all your questions will be
answered forever.
:-)

Full disclosure: I'm not so much preoccupated with the exact definition
of objects, arrays and hashtables: I'm not a CS theory professor. But
as an A.I. hobbist I'm really interested in the process the mind is
escaping the real world facts to save the predefined internal model.

You may enjoy (I did) reading the article "javascript: Playing Numbers
Game":
<http://www.devx.com/webdev/Article/17215/0/page/3>

Besides some very intersting facts about the JavaScript internal
mechanics, it was for me a wonderful example of ability to make totally
wrong conclusions based on totally correct facts - just to keep the
world "as it should be".

Nov 23 '05 #23
VK wrote:
Thomas 'PointedEars' Lahn wrote:
The language implementations you tested with are based on that canon,
more, they claim to be compliant to it. Any empirical proof you provide,
considering that the result is indeed unique (especially timing tests in
such short intervals are unreliable, taking caching, multitasking and
other factors to affect run-time into account) is perhaps valuable
regarding a specific version of a specific user agent on a specific
computer, however it does not bear meaning as a general test case and so
it inappropriate to refer to for general design decisions. Especially as
you are merely making unqualified assumptions what may or may not be
without being able to provide any proof for it, because we are dealing
with Closed Source except of Mozilla/5.0 based user agents.

You see, there are a whole lot of ifs here. Ignoring them in
your argumentation certainly do not make it a more convincing one.


I see... All empiric experiments are based on imperfect real world
systems so their results are not reliable in any given case. From the
other side ECMA specifications are based on pure mental compositions
without interception with the real world - therefore they are perfect
by their very nature [...]


No, you have still not understood.
PointedEars
Nov 23 '05 #24
Lasse Reichstein Nielsen wrote:
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
And how does the first paragraph of the Array object specification fit
in? There is clearly either replacing or additional property handling
defined for those objects, see below.

...
The specification seems to produce a contradiction by itself here.
In section 8.6.2 in restricts the difference to the [[Put]] method,
in section 15.4 it specifies "special treatment to a certain class
of property names."


No contradiction. There is special treatmet for a certain class of
property names (array indices and "length"). The special treatment
only occurs when you write to properties of those names, but it is
still special treatment.


Not true. It also happens when reading those properties.

var a = [1, 2, 3];
alert(a["2"]); // yields 3 (in Firefox 1.0.7/Linux)
PointedEars
Nov 23 '05 #25
VK
Thomas 'PointedEars' Lahn wrote:
No, you have still not understood.


Dead lock... as usual...

Let's us call arrayObject[Integer] vs. arrayObject[String] benchmark
advantage as "undocumented wrong behavior demonstrated by many
browsers"? I'm fine with that. At least we could move on some coding
ideas out of all these theoretical disputes.

And still read the article I mentioned - it seemed to me (I may be
wrong) that the magic of the number 4294967295 in many programming
languages (not only JavaScript) was not totally clear by you.

Nov 23 '05 #26
"VK" <sc**********@yahoo.com> writes:
Honnest the God I did not plan to make a trolling thread here - I
really wanted to find the most productive solution for my methods.
Unfortunately I have to conclude that I'm on my own in that as everyone
else is using wrong model, that gives totally wrong benchmark
predictions and totally wrong explanations (or no explanation at all)
to the benchmark results.


I think we have been talking about the subject from different angles.
If you entire point is that the current implementations implement
objects with special handling of numeric indices, then it appears
to be correct. The explanation using "casting" and "Baby Care" isn't
very clear, though. It can be stated much shorter, e.g.:

ECMAScript uses strings for property names. Doing a lookup on
a number gives the same as first converting the number to a
string.

Many current implementations optimize lookup by numbers by using
the numbers as keys internally, instead of their string representation.
That means that a lookup with a number index is faster in such an
implementation, than using a string representation of the number.
This is the opposite of a literal implementation of the ECMAScript
algorithms, which would use time converting the number to a string
first.

This optimization is commonly applied to all objects, not just arrays.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #27
Thomas 'PointedEars' Lahn <Po*********@web.de> writes:
Not true. It also happens when reading those properties.

var a = [1, 2, 3];
alert(a["2"]); // yields 3 (in Firefox 1.0.7/Linux)


There is no *special* treatment here.

The variable "a" refers to an array object. It has properties named
"0", "1", "2", and "length". Evaluating a["2"] looks up the value
of the property "2", which is the number 3. The same would be
true of the object
{"0":1, "1":2, "2":3, "length":3}
The [[Get]] method executes the same steps for the array as for
this object. Nothing special happens for the array.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Nov 23 '05 #28
VK
Lasse Reichstein Nielsen wrote:
I think we have been talking about the subject from different angles.
If you entire point is that the current implementations implement
objects with special handling of numeric indices, then it appears
to be correct. The explanation using "casting" and "Baby Care" isn't
very clear, though. It can be stated much shorter, e.g.:

ECMAScript uses strings for property names. Doing a lookup on
a number gives the same as first converting the number to a
string.

Many current implementations optimize lookup by numbers by using
the numbers as keys internally, instead of their string representation.
That means that a lookup with a number index is faster in such an
implementation, than using a string representation of the number.
This is the opposite of a literal implementation of the ECMAScript
algorithms, which would use time converting the number to a string
first.


You just did the first really crucial step in your new life: you
questionned The Book and tried to find a new reading to old texts.
Still long way to go but the step is done.
;-)

Here's some homework to do: ;-)

[1]
var hashObject = {};
var arrayObject = [];

/* Hashtable and Array are different objects
* with different structure and method/property sets:
*/
alert(hashObject instanceof Array); // false
alert(arrayObject instanceof Array); // true

/* But both Hashtable and Array are extending
* basic Object constructor, so whetever Object
* has, Hashtable and Array have too:
*/
alert(hashObject instanceof Object); // true
alert(arrayObject instanceof Object); // true

[2]
var tmp = 1;
alert(typeof tmp); // "number"
tmp = "";
alert(typeof tmp); // "string"
tmp = true;
alert(typeof tmp); // "boolean"

/* Does the above prove that there are no
* numbers, strings and booleans in JavaScript
* but only some amorphium "data holder"?
* Of course not! It just shows that JavaScript
* implements run-time typezation if needed.
*/

[3]
JavaScript was never written by ECMA standards.
ECMA standards are written by exploring pre-existing closed source
JavaScript engine (in Netscape Navigator). Whatever the team did not
see or did not understand properly went into papers as well as totally
correct descriptions (the right part still constitutes the total
majority of ECMA specs).

P.S. God damn! And I hopped to work closer on my jsFileManager this
week-end... :-(

Nov 23 '05 #29
VK wrote:
Thomas 'PointedEars' Lahn wrote:
No, you have still not understood.

Still no proper quoting. Why am I not suprised?
Dead lock... as usual...


I beg your pardon? I tried to explain to you shortly and in great length
that your very approach of evaluation of code efficiency is based on a
major basic misconception and you did not even bother to look into what it
took me much of my free time to detail for you. Now you dare accusing me
of blocking the discussion? Go away!
PointedEars, Score adjusted
Nov 23 '05 #30
VK said the following on 11/13/2005 10:39 AM:

<snip>
JavaScript was never written by ECMA standards.


That line, in and of itself, explains 100% why I don't have any more
faith in what ECMA says than I do. It's a good theory about how things
should be, but its a crappy indicator of how things really are. When the
browsers (most notably MS) actually match what ECMA says (or vice versa)
then I will start worrying about it. Until then, I care more about what
the browsers actually do instead of what ECMA says they should do.

<snip>
--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

Nov 23 '05 #31
VK

Randy Webb wrote:
That line, in and of itself, explains 100% why I don't have any more
faith in what ECMA says than I do. It's a good theory about how things
should be, but its a crappy indicator of how things really are. When the
browsers (most notably MS) actually match what ECMA says (or vice versa)
then I will start worrying about it. Until then, I care more about what
the browsers actually do instead of what ECMA says they should do.


Do not try to be more royalist than the king himself ! :-D

ECMA 262 Specifications ("ECMA") is a description of a working engine
(Netscape Navigator 4.5) made through the extensive testing and
consultations with Netscape specialists. The main task was to give such
description of this engine that anyone could build another engine which
does exactly the same things.
It doesn't cover at all (and it couldn't) the exact implementation of
each feature. Also some errors has been made in some descriptions. So
"fully ECMA compliant" engine is an engine that mimics each position in
the ECMA even if the internal process is completely different. So if
ECMA says "And here we have a string" and you (oops!) using integers,
you be good boy - take this integer, convert it into string and provide
to the interface.
But when performance becomes the primary issue you indeed should work
on the actual implementation - exactly as you're going from C++ on
assembly codes to get the last drop from your PC.

Nov 23 '05 #32
VK wrote:
<snip>
Here's some homework to do: ;-)

[1]
var hashObject = {};
var arrayObject = [];

/* Hashtable and Array are different objects
In what sense are they different objects. Any Array or Object instance
will inevitably be a distinct object, but there is nothing presented
here to indicate that they are different types of object. And as
javascript only has one Object type any claim that they are different
type of object would need some evidence to support it.
* with different structure and method/property sets:
So, possibly still the same type of object with different initialisation
([[Prototype]], [[Class]] and [[Put]] assignments) as required by ECMA
262.
*/
alert(hashObject instanceof Array); // false
alert(arrayObject instanceof Array); // true
100% in accordance with ECMA 262.

So what is the point that you think you are making with this? And how
meaningful is it when you consider:-

function myObject(){
; //...
}
myObject.prototype = [];
var x = new myObject();

alert(x instanceof Array); //alerts true;

- when - x - is certainly not an Array?
/* But both Hashtable and Array are extending
* basic Object constructor,
Justify the use of 'extending' in a language that is not class-based and
where augmentation is the specified process of turning the native object
into an Array.
so whetever Object
* has, Hashtable and Array have too:
*/
alert(hashObject instanceof Object); // true
alert(arrayObject instanceof Object); // true
100% in accordance with ECMA 262.

But all that is being said is that there is an object on the prototype
chain of both Arrays and objects. The same is also true of regular
expressions and functions:-

alert(function(){;} instanceof Object); //alerts true
alert(/a/ instanceof Object); //alerts true
[2]
var tmp = 1;
alert(typeof tmp); // "number"
tmp = "";
alert(typeof tmp); // "string"
tmp = true;
alert(typeof tmp); // "boolean"

/* Does the above prove that there are no
* numbers, strings and booleans in JavaScript
* but only some amorphium "data holder"?
It shows that values have types (but not that many) and
variables/properties can hold any type. 100% in accordance with ECMA
262. So what is the point you are trying to make here?
* Of course not! It just shows that JavaScript
* implements run-time typezation if needed.
You are making up your own terminology again, it doesn't promote your
cause. There is no type-conversion (and certainly no casting) going on
here. All that is happening is that you are assigning values of
different types to a variable/property that can hold any type.
*/

[3]
JavaScript was never written by ECMA standards.
ECMA standards are written by exploring pre-existing closed
source JavaScript engine (in Netscape Navigator). Whatever
the team did not see or did not understand properly went into
papers as well as totally correct descriptions (the right part
still constitutes the total majority of ECMA specs).


One of the drawbacks with never reading ECMA 262 for yourself is that
you would miss the list of contributors. That list includes Brendan
Eich, ever heard of him?

<URL:
http://wp.netscape.com/comprod/colum...vators_be.html >

Richard.
Nov 23 '05 #33
VK wrote:
Richard Cornford wrote:
News posts carry a 'References' header that describes the sequence of
messages and responses into which the new message fits. Your message has
the 'References' header:-

References:
<11**********************@g14g2000cwa.googlegroups .com>
<11*****************@PointedEars.de>
<11**********************@f14g2000cwb.googlegroups .com>
<1x**********@hotpop.com>
<11*********************@g47g2000cwa.googlegroups. com>
<sl**********@hotpop.com>
<12****************@PointedEars.de>
<11**********************@g44g2000cwa.googlegroups .com>
<ac**********@hotpop.com>

- in which no posts by me appear at all. The final message Id in that
header is the message to which your message is claming to be a response,
and that message was written by Lasse Reichstein Nielsen. So why are you
posting a reply to Lasse but quoting me and are apparently replying to
me?

Is it rally that difficult for you to actually reply to the message to
which you seem to want to be replying?
100% in accordance with the behaviour specified in ECMA 262.
I'm not arguing with you any more.


You never do argue anyway. Al you do is make a series of bizarre
statements, someone tells you why you are wrong (or irrelevant, or
misguided, or whatever) and you either ignore them compliantly or whine
about being criticised. It gives the impression that you don't have any
real justification for the assertions that you make and are indeed
making it all up off the top of your head.
There are reasons to argue only if the final aim is
to find the true between each other arguments.
Yes the point of arguing is to come to some mutual understanding. But if
you will never explain what you are talking about when you say things
like "Array's Object envelope", "the length flag", "turns on JavaScript
Baby Care mechanics", " Invalid array index value", "Array-mode to
Hashtable-mode", "interpreter both add new array element [33] and new
property "33"", " Object<>Array back and forth casting", etc, there is
little hop of understanding. Without explanation of what you mean when
you say these strange things the impression is that you are just
gibbering incoherently.
It's a vasted time if any fact is accepted if, and only if,
it fits to the books of canon.
What facts? You still have not stated what the urban legend you spoke of
was supposed to be, or stated whatever it was that was supposed to be
"dispropaganded". All you did was post a sequence of code statements
that demonstrated behaviour in accordance with the specification. As the
theory is that conforming ECMAScript implementations will exhibit
behaviour that conforms to the specification, and so that the
specification can be employed as a guide to the behaviour of conforming
ECMAScript implementations (indeed that it is the only guide to the
behaviour of such implementations) you appear to have expended effort
demonstrating nothing.
Honnest the God I did not plan to make a trolling thread
here - I really wanted to find the most productive solution
for my methods.
And by "productive solution" do you by any chance mean that you want to
know which type of property accessor, using which type of property name
provides the fastest results when used with Objects and Arrays. You
don't have to go off into the made-up world of VKScript to find that
out, you just have to do some experiments, as Lasse did.

It is also a good idea to actually think about the results you get.
Lasse produced a range of results form 406 to 1093 milliseconds for one
million loop iterations. And timed:-

1. The resolution of the Identifier - obj - against the scope
chain, 1000000 times.
2. The resolution of the Identifier - prop - against the scope
chain, 1000000 times.
3. The retrieval of the value from - obj - using prop (the
part of the process that is of interest here) , 1000000 times.
4. The resolution of the identifier - x - against the scope
chain, 1000000 times.
5. The assignment of the value retrieved to x, 1000000 times.
6. The overhead of each iteration of the while loop (including
the post decrement operation) , 1000000 times.
7. The creation of a Date object, once.

So a worst-case per-loop timing of 0.001093 milliseconds, in which the
operation of interest is only one of a number of operations performed,
suggests that this is a quest for speed in the wrong place. Particularly
when you consider that results will vary between implementations (as
they will rarely use the same optimisations except by coincidence), that
the timing resolution is no better than 10 milliseconds, that the type
of CPU and the CPU type plus OS combination can be a significant factor
and that any test are likely to be performed on a multitasking OS with
the number of background tasks influencing the outcome.

So there is unlikely to be a definitive answer to the question, and the
actual differences are going to be so tiny as to have little impact on
the results.
Unfortunately I have to conclude that I'm on my own
in that as everyone else is using wrong model,
Most people (with the possible exception of the mentally ill) would take
the discovery that nobody else can be persuaded that they are right as
reasonable gourds for questioning their beliefs.
that gives totally wrong benchmark predictions and totally
wrong explanations (or no explanation at all) to the
benchmark results.
Who is giving benchmark predictions? The explanation for actual
implementations producing performance differences that do not correspond
with those that would be expected if the ECMA algorithms were slavishly
followed by implementations is that implementations are not required to
follow the algorithms, only to behave as if they were following the
algorithms. Internal optimisations are allowed. ECMA 262 defines
behaviour not performance.

Where you are constantly disagreed with is in your desire to make up
stories to explain behaviour that is already well defined. Those stories
do not help people understand the task and problems of programming using
javascript.
That would be like asking someone who's using flat model
of Earth for an advise of the best way from Europe
to China through America.

<snip>

If, finding yourself in a minority of one, you don't like the appeal to
numbers, have you considered the appeal of effective outcomes. You will
recall that you spent months struggling with writing effective event
handlers, misunderstood and disregarded numerous explanations of what
was actually happening (given by some the people you consider to be
using the wrong model) and still (based on the rubbish in some of your
recent posts on the subject) do not fully understand the mechanics of
event handlers. And all this time you were surrounded by people using
the 'wrong model' who were having no trouble successfully using event
handlers. This 'wrong model' is being promoted because it is an
effective way of understanding the behaviour of the language being used,
it produces results.

You are the one falling to get to China.

Richard.

Nov 23 '05 #34
VK
> >> Richard Cornford wrote:

News posts carry a 'References' header that describes the sequence of
messages and responses into which the new message fits. Your message has
the 'References' header:-

References:
<11**********************@g14g2000cwa.googlegroups .com>
<11*****************@PointedEars.de>
<11**********************@f14g2000cwb.googlegroups .com>
<1x**********@hotpop.com>
<11*********************@g47g2000cwa.googlegroups. com>
<sl**********@hotpop.com>
<12****************@PointedEars.de>
<11**********************@g44g2000cwa.googlegroups .com>
<ac**********@hotpop.com>

- in which no posts by me appear at all. The final message Id in that
header is the message to which your message is claming to be a response,
and that message was written by Lasse Reichstein Nielsen. So why are you
posting a reply to Lasse but quoting me and are apparently replying to
me?

Is it rally that difficult for you to actually reply to the message to
which you seem to want to be replying?


Must be wrong schooling:- I always to following the main thread so my
post would add up at the and of the line w/o making new thread branch.
Sometimes few more replies are already staying in front of the post I'm
answering to. Also sometimes I'm doing a cummulative reply to several
posts as they are close connected. I used to think that the exact
indication of the author of the quote is more convenient than post
headers lookup. Am I so wrong?

Nov 23 '05 #35
VK
Cummulative answer to Richard Cornford:

If you go to my OP you'll see that I did not want I did not make any
"points". I simply asked for the fastest algorythm for my method. Now
read all these 30+ posts and see what did I get and who's really making
a final pointless point.

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.

I'm asking for an advise and what kind of bs am I getting instead:

- There is no array and hash, so doesn't matter what are you using -
read ECMA
- But there is a benchmark difference on all browsers I've tested !
- There is no any difference, your tests are not accurate - read ECMA
- Can you provide a code for an accurate test?
- No test can be accurate as too many circumstances are involved - read
ECMA instead
etc. etc. etc.

That would drive crazy any less stable person, my sense of humor helps
greatly but not always.

OK, listen, guys: I asked for the best performance algorythm, you
explaned me that any is equally good as I'm dealing with the same
entity. I listened you, I'm saying thank you for you help, I'll think
about it.

Topic is over.

Nov 23 '05 #36
VK wrote:
>> Richard Cornford wrote:
^^^^^
Can't you get this right just the once?

<snip> So why are you posting a reply to Lasse but quoting me
and are apparently replying to me?

Is it rally that difficult for you to actually reply to
the message to which you seem to want to be replying?
Must be wrong schooling:- I always to following the main thread


There is no such thing as a "main thread" in Usenet.
so my post would add up at the and of the line
What "line"?
w/o making new thread branch.
It is in the nature of Usenet conversations to branch, there is no need
and no point in trying to avoid that, and your actions do not achieve
that anyway.
Sometimes few more replies are already staying in front
of the post I'm answering to.
And that is relevant to what exactly?
Also sometimes I'm doing a cummulative reply to
several posts as they are close connected.
And you shouldn't be doing that anyway.
I used to think that the exact indication of the
author of the quote is more convenient than
post headers lookup.
Headers are used to organise the presentation of posts in newsreaders,
they are more important to the presentation of threaded conversation
than anything else.
Am I so wrong?


You certainly appear not to have any idea of what you are doing, again.

Richard.
Nov 23 '05 #37
VK wrote:
Cummulative answer to Richard Cornford:
An "answer" that does not contain a single answer to any of the
questions that I asked. It is that attitude that is getting in the way
of your actually learning anything useful here.
If you go to my OP you'll see that I did not want I did
not make any "points".
I looked at you original post and found it too incoherent and inadequate
to be addressed with anything but guesswork and elected not to bother.
I simply asked for the fastest algorythm for my method.
That was not apparent, but as you did not elaborate your method it would
not be practical to suggest what may be faster or slower.
Now read all these 30+ posts and see what did I get and
who's really making a final pointless point.
So you have no intention of explaining what all of that nonsense you
posted was supposed to be about?
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.
Hundreds of files? You strategy must be appallingly bad is only hundreds
of items are procuring such appalling performance. If you were talking
about thousands of items you may be looking at seconds.
I'm asking for an advise and what kind of bs am I getting
instead:
Your asking for advice is being ignored. Mostly because you are
incapable of expressing you question coherently. What is happening is
that you are making bizarre assertions and refusing to provide any
explanation when asked what you are talking about.
- There is no array and hash, so doesn't matter what are
you using - read ECMA
- But there is a benchmark difference on all browsers I've tested !
You have presented no evidence that you have tested anything, or how you
have tested it. Given your record on testing logic and methodology, and
your atrocious Math, your clams alone are unlikely to be given credence.
- There is no any difference, your tests are not accurate
- read ECMA
- Can you provide a code for an accurate test?
No, accurate testing is not possible. I can write tests that produce
more accurate results, but I have already explained the flaws in your
testing a couple of times so you should be able to work out the logic of
the necessary tests for yourself. (or use the archives to find superior
examples to work from).
- No test can be accurate as too many circumstances are involved -
read ECMA instead
etc. etc. etc.

That would drive crazy any less stable person, my sense of
humor helps greatly but not always.

OK, listen, guys: I asked for the best performance algorythm, you
explaned me that any is equally good as I'm dealing with the same
entity.
That may have been your 'understanding' of what has been explained, but
that fact that that statement is incoherent indicates that it was not
what actually was explained, and that you did not understand.
I listened you, I'm saying thank you for you help, I'll think
about it.

<snip>

That will make an unexpected change.

Richard.
Nov 23 '05 #38
VK wrote:
ECMA 262 Specifications ("ECMA")
ECMA is the acronym for the European Computer Manufacturers Association,
an international standardization body. It is _not_ the name of one of the
standards published by that body.

There is only one ECMA-262 (ECMAScript) Specification, yet there are several
editions of it. The most recent one is edition 3.
is a description of a working engine (Netscape Navigator 4.5) made through
the extensive testing and consultations with Netscape specialists.


No, it is not! What you write is absolute complete utter nonsense!
As can be read in its preface (any edition), for example

,-<http://www.mozilla.org/js/language/E262-3.pdf>
|
| [...]
| Brief History
|
| This ECMA Standard is based on several originating technologies, the most
| well known being JavaScript (Netscape) and JScript (Microsoft). The
| language was invented by Brendan Eich at Netscape and first appeared in
| that company?s Navigator 2.0 browser. It has appeared in all subsequent
| browsers from Netscape and in all browsers from Microsoft starting with
| Internet Explorer 3.0.

But then again, you never bothered to read *any* specification.
PointedEars
Nov 23 '05 #39

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Peter Nofelt | last post by:
Hey all, I am running into an issue. My situation is that I wish to copy the contents of one listbox to an array, sort it by innerText value, and write the sorted options into a new listbox. ...
16
by: sneill | last post by:
How is it possible to take the value of a variable (in this case, MODE_CREATE, MODE_UPDATE, etc) and use that as an object property name? In the following example I want 'oIcon' object to have...
8
by: Michael B Allen | last post by:
I would like to know your preferences regarding a C API for a hash map. Specifically, when inserting a data item into a hash map there are two special cases that require consideration. 1) If two...
6
by: Joseph Lee | last post by:
Dear All, Is there a function in C# that will hash code a large byte array into an int value? I am searching for a hash function that will convert any size data(as for me the input is a byte...
6
by: Chang | last post by:
How to get SHA1 or MD5 of a big file (+5MB - 20GB) as I can't read 20GB into memory. -- Chang.
6
by: Jake Barnes | last post by:
I was just reading this article on Ajaxian: http://ajaxian.com/archives/show-love-to-the-object-literal This is a newbie question, but what is the object literal? I thought it was like an...
2
by: nacho222 | last post by:
I'm currently in the middle of writing a persistence framework, and I have to make a design decission. The framework will take care of all the saving and restoring objects, and also the...
275
by: Astley Le Jasper | last post by:
Sorry for the numpty question ... How do you find the reference name of an object? So if i have this bob = modulename.objectname() how do i find that the name is 'bob'
1
by: sixtyfootersdude | last post by:
Good Morning! I am a perl newbie and I think that I am struggling with references. I have an array of references to hashes which I am trying to print. This is what I have: for(my...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.