views:

5073

answers:

7

In Actionscript 3, is there any reel overhead between importing a full package versus importing independant classes?

E.g.: import flash.display.* vs. import flash.display.Sprite

I know it's a good practice to import only the needed classes from a package to avoid conflicts, but I've often been told it also has a cost in term of the compiled file size if I import full packages in many different classes that only use some of the classes from those packages.

I wonder if one class will be imported once for all for the whole project, or if imports are multiplied among the classes that use them.

Resulting compiled file size and runtime performance are two different aspects this question embraces.

A: 

As with most languages there is little or no performance overhead related to importing entire packages rather than individual classes.

However it is more a good practice since it gives a much more concise veiw of dependencies for your class

Jambobond
A: 

The ActionScript 3 spec says all public names from the package will imported if you use the '*'. So there is a hit, although it may not be a large one depending on the package size. The ActionScript Design Patterns book also discourages this due to excess baggage, as well as some Adobe ActionScript tips.

That being said, I took one as component in an app I wrote and

  import mx.containers.*;
  import mx.events.*;
  import mx.managers.*;

Instead of the single class names. My size increased by 3 bytes. Now, the entire app is 935kB, so I probably have those classes imported elsewhere, and the hit wasn't very big. I bet the smaller your application is, the larger the impact on your compile size will be(percentage wise).

ryanday
A bit disapointing that the compiler can not optimize that.
Lillemanden
But I think more optimization means more time to compile(publish), Flash AS3 is pathetically slow in publish process. So In my opinion, first they should make it better(something like higher languages, compile only deltas) and faster then they should think about these optimizations. !!! :)
Bhavesh.Bagadiya
+2  A: 

The only hit should be compile time, but rday writes that there is apperently a small hit. But that should be something that Adobe will fix in the future.

The import statements should not really be looked on as actual imports, it is merely a way for the compiler to know which classes you are refering to.

eg. If you made you own Point class and it was being used in another package, the compiler needs to know if you are refering to your own Point class or the Adobe Point class.

The alternative would be to write the fully qualified name evertime you refered to a class.

eg. var mySprite:flash.display.Sprite = new flash.display.Sprite();

As pointed out by Juan Pablo Califano in the comment, this does not actually work with the compiler (though I think it might work with AS2). I merely meant to point out why we have import statement to begin with.

In any case it should not effect the compiled file if you import a whole package (though it apperently does). It will how ever effect compile time, since you are giving the compiler more stuff it needs to look through.

As for "importing" the same class more than once. It will not make a difference. The compiler will only include the same class once. Else the compiled file size would quickly spin out of control, since most classes refer to many classes which again refer to others etc. But again, Adobe might have optimizing to do there.

Bottom line is you should only import the stuff you need, there is no real advantage to importing a whole package. Just use a proper coding tool like FlashDevelop (it is free) and you do not even have to write the import statements yourself.

On a side note, if you are compiling a library (where a class not refered to are also included), im not sure if importing a external package might include that in you compiled file. That might have an actual impact; though hopefully Adobe did not screw up there ;)

Lillemanden
Just a note: even if you use the fully qualified path in your code, you need the import or else the compiler will complain.
Juan Pablo Califano
True, I forgot that. But it was more meant as a point as to why we have the import statements, since the alternative would be very annoying.
Lillemanden
No problems. And yes, that was the behaviour in AS 2. If you used the fully qualified name, you could omit the import.
Juan Pablo Califano
A: 

good practice is in general to have code that is readable ... having a class start with 200 import statements thus would be rather bad practice ...

in as3, an import statement only adds a new scope to the compiler's identifier resolution ... what is compiled into an SWF and what is not, is not determined by the import statements, but by actual dependancies, i.e. code from class A using class B ...

so at runtime it does not make any difference, how you imported your classes ...

back2dos
+1. I personally like importing explicitly every class. I'd think it twice if I had to do it manually, though. But, anyway, you're right about how import works. It's a compiler directive, but it doesn't force compilation. Otherwise, why would anyone use the "var dummy:SomeClass;" hack to force the inclusion of a class not referenced as such in code?
Juan Pablo Califano
+1  A: 

There is absolutely no difference in the compiled code whether you import the entire package or just the classes you are using. Imports are just important for the compiler to find where the classes are.

You can try to decompile or look at the bytecode before and after.

Ammar
A: 

You can check exactly what classes are being imported by using the 'link-report' compiler option

The compiler may take longer to sort out what to include and what not to include, but if you check out your link reports, you'll notice it only includes what it uses. :)

secoif
+1  A: 

Addressing ryanday's points, I can't explain the extra 3 bytes, but a few notes...

"The ActionScript Design Patterns book also discourages this due to excess baggage"

Yep, on page 115, but I think it is wrong and submitted errata to that effect.

"The ActionScript 3 spec says all public names from the package will imported if you use the '*'. So there is a hit, "

It kind of does, but I disagree re the interpretation and hit. It says: "The names of package members are made visible..." (in full). In this context, it is referring to making names of members visible to the compiler and editor tools, not visible within the compiled SWF. i.e. does not mean the classes get compiled into the SWF - unless they are actually used (a variable declared of that type).

Another way of looking at this, you could manually import flash.display.MovieClip. But if you don't create any instance of MovieClip, the MovieClip class will not get compiled into the final SWF.

To satisfy myself, I compiled the following helloworld in 3 ways, outputting link-report as suggested by @secoif...

package
{
    import flash.display.Sprite;
    import flash.text.TextField;

    public class ASHelloWorld extends Sprite
    {
        public function ASHelloWorld()
        {
            var tf:TextField = new TextField();
            tf.text = "Hello World!";
            addChild( tf );
        }
    }
}

First, as written, link report:

<report>
  <scripts>
    <script name="~/Documents/eclipse3.5carbonFbPlugin-FX4-LS10/ASHelloWorld/src/ASHelloWorld.as" mod="1278415735000" size="682" optimizedsize="344">
      <def id="ASHelloWorld" />
      <pre id="flash.display:Sprite" />
      <dep id="AS3" />
      <dep id="flash.text:TextField" />
    </script>
  </scripts>
  <external-defs>
    <ext id="AS3" />
    <ext id="flash.text:TextField" />
    <ext id="flash.display:Sprite" />
  </external-defs>
</report>

Second, delete the link report file and change imports to:

    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.text.TextField;

Clean build, and the link report looks exactly the same. Same size, same optimizesize, same linked classes.

Third, delete the link report file and change imports to:

    import flash.display.*;
    import flash.text.*;

Clean build, and the link report looks exactly the same. Same size, same optimizesize, same linked classes.

Only Sprite and TextField classes make it to the SWF in each case.

Looking at the actual SWF file size on disk, there does seem to be a slight (1 or 2 byte) variation over the 3 versions. No worse than for the larger SWF referred to in ryanday's post.

creacog