eep. We should definitely go through the code and clean up comparisons with
sentinel objects or other constant objects. Interesting to see if anything
breaks when we do that too...

On Sat, May 2, 2009 at 7:05 PM, P T Withington <[email protected]> wrote:

> So I'm profiling along, and I find an anonymous function that is being
> called a number of times.  It doesn't cost a lot, but I'm curious why it is
> anonymous.  It's not really anonymous, because our compiler assigns a
> debugging name to anonymous functions that you can use to find them in the
> source.  Here's the anonymous function:
>
>   static var _ignoreAttribute = {toString: function () {
>>      return '_ignoreAttribute'}};
>>
>
> _ignoreAttribute is just a unique sentinel object that we use as a way to
> indicate that an attribute has already been processed, deep in the inner
> workings of LZX.  Someone (probably me) graciously gave it a `toString`
> method, so that when you are debugging and trip across it, you will realize
> that it is not just any old empty object.
>
> But I'm not debugging.  I'm profiling.  I'm not calling
> `_ignoreAttribute.toString()`.  It's nowhere in the source code that I can
> see.  What is going on?  Well, here's a problem:
>
>     if (null != this.datapath && dp != LzNode._ignoreAttribute) {
>>      this.datapath.setXPath(dp);
>>    } else {
>>
>
> Can you spot it?  When `dp != LzNode._ignoreAttribute` runs, `dp` is
> normally a string, and read the fine print for how equality is computed in
> Javascript (from p. 64 of "ECMAScript Language Specification   Edition 3"):
>
>  1. If Type(x) is different from Type(y), go to step 14.
>> [...]
>> 20. If Type(x) is either String or Number and Type(y) is Object,
>> return the result of the comparison x == ToPrimitive(y).
>>
>
> Well, I won't bore you with more gory details, but the bottom line is,
> every time we compare `_ignoreAttribute` to a String, the runtime has to
> call its `toString` method to see if it is "equal".
>
> The storal of the morey is, when you want to compare for "identity", use
> the "strict equals operator" (`===` or `!==`), not the "equals operator".
>  [For my money, the former should have just been called the "identity"
> operator, but unfortunately it isn't quite.  There are some odd edge cases
> that make it not a _true_ identity operator.]
>



-- 
Henry Minsky
Software Architect
[email protected]

Reply via email to