Now that the release is out, I spent some more time looking into the issue
of what variables should be initialized and thus, how we should handle
equality testing (==, ===, etc).  My conclusion remains the same:  there
is no one right answer.  But I saw some interesting things.

I started with the test case in
https://issues.apache.org/jira/browse/FLEX-35330 and added to it.  I was
concerned that the test case loop performance could be skewed by runtime
loop optimizations.  Our code doesn't have many long loops.  Our equality
testing is scattered throughout the code as objects are instantiated and
user interaction causes changes.  And also note, one of the points of
beads and PAYG is to reduce the number of equality tests in the final
output.  IOW, if your app isn't going down both code paths of an if
statement, then a lightweight bead could eliminate that test.

So, I wanted to make sure any runtime code flow would think that the loop
variables might change so they don't extract it to a constant outside of
the loop.  I decided to use the Date() class and its getFullYear() as the
thing that might change but doesn't.  You can see the newer test by
downloading Main.mxml
http://home.apache.org/~aharui/FlexJS/FLEX35330/src/Main.mxml

The "work" in the loop now looks more like:
    var obj:Object;
    var now:Date = new Date();
    if (now.getFullYear() < 2016)
        obj = {}; // should never get here, but flow analysis shouldn't
know that
    return (obj != null) ? Math.random() : 0;


The JS version of the test is here:
http://home.apache.org/~aharui/FlexJS/FLEX35330/bin/js-release/
The SWF version of the test is here:
http://home.apache.org/~aharui/FlexJS/FLEX35330/bin-debug/

For me, the SWF version is considerably slower.  The JS version can run a
test in 200ms that takes Flash 12000ms!

But more interestingly, this version of the test also checks the code
pattern:

  if (someObject)

And for me, on both SWF and JS, I'm seeing that run as fast or faster for
"boolean" as using strict equality:

  if (someObject === true)

Do others see that?  Because if that's true (and it isn't a bug in the
test), given that "if (someObject)" doesn't require boolean variable
initialization and is smaller code on both platforms, it seems like that
would be a pattern the compiler should support and would get my vote as
the default pattern.

We certainly want to support those that want to use strict equality in
places where "*' isn't used, but in this test, the difference is
negligible.  Google Closure Compiler isn't currently smart about member
variable initialization so each initialized variable adds a few bytes to
the minified JS.  It might GZIP out.  I didn't try that yet.

Google's optimizer/minifier is pretty aggressive about code rewriting.
The snippet above ends up looking something like:
  var a=null;2016>(new Date).getFullYear()&&(a={});return
null!=a?Math.random():0

It got me thinking about an option where the compiler will rewrite usage
of strict equality where there is almost no performance difference in
order to reduce code size and number of variables that need initialization.

Again, we don't have to all agree.  We can teach the compiler to do
different things at different points.

Thoughts?
-Alex



Reply via email to