【问题标题】:Actionscript 3 import package.* vs import package.ClassActionscript 3 import package.* vs import package.Class
【发布时间】:2010-11-18 14:01:13
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: actionscript-3 optimization import packages


    【解决方案1】:

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

    import 语句不应该被视为真正的导入,它只是让编译器知道你所引用的类的一种方式。

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

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

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

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

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

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

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

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

    【讨论】:

    • 请注意:即使您在代码中使用完全限定路径,也需要导入,否则编译器会报错。
    • 是的,我忘记了。但它更多地意味着为什么我们有 import 语句,因为替代方案会非常烦人。
    • 没问题。是的,这就是 AS 2 中的行为。如果您使用完全限定名称,则可以省略导入。
    【解决方案2】:

    针对ryanday的观点,我无法解释额外的3个字节,但是一些注释......

    《ActionScript 设计模式》一书也不鼓励这样做,因为包袱过多

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

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

    确实如此,但我不同意这种解释和打击。它说:“包成员的名字可见...”(in full)。在此上下文中,它指的是使成员的名称对编译器和编辑器工具可见,而在已编译的 SWF 中不可见。也就是说,是否意味着类被编译到 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 差。

    【讨论】:

      【解决方案3】:

      ActionScript 3 spec 表示如果您使用“*”,将导入包中的所有公共名称。所以有一个打击,虽然它可能不是一个大的,具体取决于包装大小。 ActionScript Design Patterns 这本书也因行李过多而劝阻这种做法,还有一些 Adobe ActionScript tips

      话虽如此,我在自己编写的应用程序中使用了一个组件

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

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

      【讨论】:

      • 但我认为更多的优化意味着更多的时间来编译(发布),Flash AS3 在发布过程中慢得可怜。所以在我看来,首先他们应该让它变得更好(比如高级语言,只编译增量)并且更快,然后他们应该考虑这些优化。 !!! :)
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        您可以使用'link-report' compiler option准确检查正在导入的类

        编译器可能需要更长的时间来区分哪些内容需要包含哪些内容不能包含在内,但如果您查看链接报告,您会发现它只包含了它使用的内容。 :)

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            一般来说,良好的做法是编写可读的代码...以 200 个导入语句开头的类因此将是相当不好的做法...

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

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

            问候

            back2dos

            【讨论】:

            • +1。我个人喜欢明确地导入每个类。不过,如果我必须手动操作,我会三思而后行。但是,无论如何,您对导入的工作方式是正确的。这是一个编译器指令,但它不强制编译。否则,为什么会有人使用“var dummy:SomeClass;”破解以强制包含代码中未引用的类?
            【解决方案8】:

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

            【讨论】:

              猜你喜欢
              • 2014-04-21
              • 2016-08-12
              • 1970-01-01
              • 1970-01-01
              • 2023-03-07
              • 2017-02-24
              • 2018-12-09
              • 2012-07-27
              • 2020-05-11
              相关资源
              最近更新 更多