15

在 Actionscript 3 中,导入完整包与导入独立类之间是否存在任何卷轴开销?

例如:import flash.display.* 与 import flash.display.Sprite

我知道从包中只导入所需的类以避免冲突是一个很好的做法,但我经常被告知,如果我在许多不同的类中导入完整的包,它也会在编译文件大小方面产生成本,这些类只使用这些包中的一些类。

我想知道一个类是否会为整个项目导入一次,或者导入是否在使用它们的类中成倍增加。

生成的编译文件大小和运行时性能是这个问题包含的两个不同方面。

4

8 回答 8

7

唯一的打击应该是编译时间,但rday写道,显然有一个小打击。但这应该是 Adob​​e 将来会解决的问题。

导入语句不应该真正被视为实际导入,它只是编译器知道您正在引用哪些类的一种方式。

例如。如果您创建了自己的Point类并且它正在另一个包中使用,那么编译器需要知道您是在引用自己的Point类还是 Adob ​​ePoint类。

另一种方法是在您引用某个类时编写完全限定名称。

例如。var mySprite:flash.display.Sprite = new flash.display.Sprite();

正如Juan Pablo Califano在评论中指出的那样,这实际上不适用于编译器(尽管我认为它可能适用于 AS2)。我只是想指出为什么我们要从 import 语句开始。

在任何情况下,如果您导入整个包(尽管它显然会),它不应该影响编译文件。它将如何影响编译时间,因为您为编译器提供了更多需要查看的内容。

至于不止一次“导入”同一个类。它不会有所作为。编译器只会包含一次相同的类。否则编译后的文件大小会很快失控,因为大多数类引用许多类,这些类又引用其他类等。但同样,Adobe 可能需要在那里进行优化。

底线是你应该只导入你需要的东西,导入整个包没有真正的优势。只需使用像FlashDevelop之类的适当编码工具(它是免费的),您甚至不必自己编写导入语句。

附带说明一下,如果您正在编译一个库(其中还包括一个未引用的类),我不确定导入外部包是否可能会将其包含在您编译的文件中。这可能会产生实际影响;虽然希望 Adob​​e 没有在那里搞砸;)

于 2009-08-11T14:17:53.380 回答
5

解决 ryanday 的观点,我无法解释额外的 3 个字节,但有一些注意事项......

ActionScript 设计模式一书也因过多的行李不鼓励这样做

是的,在第 115 页,但我认为这是错误的,因此提交了勘误表。

ActionScript 3 规范说,如果您使用“*”,将导入包中的所有公共名称。所以有一个打击,

确实如此,但我不同意这种解释和打击。它说:“包成员的名字是可见的......”(完整)。在这种情况下,它指的是使编译器和编辑器工具可以看到成员的名称,而不是在已编译的 SWF 中可见。ie 并不意味着这些类被编译到 SWF 中——除非它们被实际使用(声明为该类型的变量)。

另一种看待这个的方式,你可以手动导入flash.display.MovieClip. 但是,如果您不创建任何 MovieClip 实例,MovieClip 类将不会被编译到最终的 SWF 中。

为了满足自己,我以 3 种方式编译了以下 helloworld,按照@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 );
        }
    }
}

首先,如书面,链接报告:

<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>

其次,删除链接报告文件并将导入更改为:

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

干净的构建,链接报告看起来完全一样。相同的大小,相同的优化大小,相同的链接类。

三、删除链接报告文件,将imports改为:

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

干净的构建,链接报告看起来完全一样。相同的大小,相同的优化大小,相同的链接类。

在每种情况下,只有 Sprite 和 TextField 类可以进入 SWF。

查看磁盘上的实际 SWF 文件大小,与 3 个版本相比,似乎确实存在细微的差异(1 或 2 字节)。不比 ryanday 帖子中提到的更大的 SWF 差。

于 2010-07-06T12:47:31.497 回答
1

ActionScript 3 规范说,如果您使用“*”,将导入包中的所有公共名称。所以有一个打击,虽然它可能不是一个大的,取决于包装的大小。《ActionScript 设计模式》一书也不鼓励这样做,因为包袱过多,以及一些Adob​​e ActionScript 技巧

话虽如此,我将一个作为我编写的应用程序的组件

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

而不是单一的类名。我的大小增加了 3 个字节。现在,整个应用程序是 935kB,所以我可能在其他地方导入了这些类,并且点击量不是很大。我敢打赌,您的应用程序越小,对您的编译大小的影响就越大(百分比)。

于 2009-08-11T11:45:09.553 回答
1

无论您导入整个包还是仅导入您正在使用的类,编译后的代码绝对没有区别。导入对于编译器查找类的位置很重要。

您可以尝试反编译或查看前后的字节码。

于 2009-08-11T18:40:29.127 回答
1

您可以使用'link-report' 编译器选项准确检查正在导入的类

编译器可能需要更长的时间来整理要包含的内容和不包含的内容,但是如果您查看链接报告,您会发现它只包含它使用的内容。:)

于 2009-11-21T17:37:59.840 回答
0

与大多数语言一样,与导入整个包而不是单个类相关的性能开销很少或没有。

然而,这是一种更好的做法,因为它为您的类提供了更简洁的依赖关系视图

于 2009-08-11T11:36:27.853 回答
0

好的做法通常是拥有可读的代码......让一个类以 200 个导入语句开始,因此将是相当糟糕的做法......

在 as3 中,import 语句只为编译器的标识符解析添加了一个新范围……什么被编译成 SWF,什么不是,不是由 import 语句决定的,而是由实际的依赖关系决定的,即来自类 A 的代码使用类乙...

所以在运行时它没有任何区别,你如何导入你的类......

问候

back2dos

于 2009-08-11T16:10:10.770 回答
0

我发现,与 AS3 相比,仅使用 import 语句将在输出中包含类,而不管这些类是否在实际代码中被引用。将此与 Java 进行对比,后者仅包含实际使用的类,而不仅仅是在 import 语句中提及。但我发现这在设计 Flash API 时很有用,只需在 import 语句中提及这些类,它们就会被包含在内。

于 2011-02-18T06:49:48.763 回答