在Actionscript 3中,导入完整包与导入独立类之间是否有任何卷轴开销?
例如:import flash.display。* vs import flash.display.Sprite
我知道从包中仅导入所需的类以避免冲突是一个好习惯,但我经常被告知如果我在许多不同的类中导入完整的包,它在编译文件大小方面也有成本只使用这些包中的一些类。
我想知道是否会为整个项目一次性导入一个类,或者在使用它们的类之间是否相乘。
产生的编译文件大小和运行时性能是这个问题所包含的两个不同方面。
答案 0 :(得分:7)
唯一的打击应该是编译时间,但 rday 写道,这显然是一个小小的打击。但这应该是Adobe将来会解决的问题。
import语句不应该真正被视为实际的导入,它只是编译器知道你所引用的类的一种方式。
例如。如果您创建了自己的Point
类,并且它正在另一个包中使用,则编译器需要知道您是在引用自己的Point
类还是Adobe Point
类。
另一种方法是将您提到的完全限定名称evertime写入一个类。
例如。 var mySprite:flash.display.Sprite = new flash.display.Sprite();
正如 Juan Pablo Califano 在评论中指出的那样,这实际上并不适用于编译器(尽管我认为它可能适用于AS2)。我只是想指出为什么我们开始使用import语句。
在任何情况下,如果你导入一个整个包(尽管它显然是这样),它不应该影响编译文件。它将如何影响编译时间,因为您为编译器提供了需要查看的更多内容。
不止一次“导入”同一个班级。它不会有所作为。编译器只包含一次相同的类。否则编译后的文件大小会很快失去控制,因为大多数类都引用了许多类,这些类再次引用其他类等。但是,Adobe可能会进行优化以便在那里进行。
底线是你应该只导入你需要的东西,导入整个包没有真正的优势。只需使用像FlashDevelop这样的正确编码工具(它是免费的),你甚至不必自己编写import语句。
另外,如果您正在编译库(其中还没有包含类),我不确定导入外部包是否可能包含在您编译的文件中。这可能会产生实际影响;虽然希望Adobe没有搞砸那里;)
答案 1 :(得分:5)
解决ryanday的观点,我无法解释额外的3个字节,但有几个注释......
“动作脚本设计模式”一书也因行李过多而不鼓励这样做
是的,在第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;
清理构建,链接报告看起来完全一样。相同的大小,相同的优化,相同的链接类。
第三步,删除链接报告文件并将导入更改为:
import flash.display.*;
import flash.text.*;
清理构建,链接报告看起来完全一样。相同的大小,相同的优化,相同的链接类。
在每种情况下,只有Sprite和TextField类可以在SWF中使用它。
查看磁盘上的实际SWF文件大小,确实有3个版本的轻微(1或2字节)变化。没有比ryanday的帖子中提到的更大的SWF差。
答案 2 :(得分:1)
ActionScript 3 spec表示如果您使用'*',系统会导入包中的所有公共名称。所以有一个打击,虽然它可能不是一个大的,取决于包装尺寸。 ActionScript Design Patterns这本书也因行李过多而不鼓励,以及一些Adobe ActionScript tips。
话虽如此,我在我编写的应用程序中选择了一个作为组件
import mx.containers.*;
import mx.events.*;
import mx.managers.*;
而不是单个类名。我的大小增加了3个字节。现在,整个应用程序是935kB,所以我可能在其他地方导入了这些类,并且命中率不是很大。我敢打赌,你的应用程序越小,对编译大小的影响就越大(百分比)。
答案 3 :(得分:1)
无论是导入整个包还是仅导入正在使用的类,编译代码都没有区别。导入对于编译器找到类的位置非常重要。
您可以尝试反编译或查看之前和之后的字节码。
答案 4 :(得分:1)
您可以使用'link-report' compiler option
确切地检查要导入的类编译器可能需要更长的时间来整理要包含的内容和不包含的内容,但是如果您查看链接报告,您会发现它只包含它使用的内容。 :)
答案 5 :(得分:0)
与大多数语言一样,导入整个包而不是单个类几乎没有或没有性能开销。
然而,这是一个很好的做法,因为它为你的班级提供了更为简洁的依赖性视角
答案 6 :(得分:0)
一般来说,良好的做法是让代码具有可读性......让一个类以200个import语句开头,这样做会很糟糕......
在as3中,import语句只为编译器的标识符解析添加了一个新的范围...编译成SWF的内容和不编译的内容不是由import语句决定的,而是由实际的依赖项决定的,即来自类的代码A使用B级......
所以在运行时它没有任何区别,你如何导入你的类......
格尔茨
back2dos
答案 7 :(得分:0)
我发现,与AS3相比,仅仅使用import语句将包含输出中的类,而不管这些类是否在实际代码中引用。将此与Java对比,如果实际使用它们,则只包括类,而不仅仅是在import语句中提到的。但是我在设计Flash API时发现这很有用,只需在import语句中提及这些类,它们就会被包含在内。