Browse > Home > Archive: 08月 2007

| Subcribe via RSS

谈谈AS中的惰性函数模式(Lazy Function Definition)

08月 31st, 2007 | No Comments , 121 views | Posted by flashlizi in Flash8/AS2

最近看了Peter的Javascript的惰性函数定义模式(Lazy Function Definition)之后,想测试下as下的这种函数模式的效率是否比一般的模式要高。不了解此函数定义模式的朋友可以看看这篇文章的翻译。我做了如下测试:
[code]
//普通函数模式
var num = 0;
function test1() {
return num++;
}
//惰性函数模式
var test2 = function () {
var num = 0;
test2 = function () {
return num++;
};
return num++;
};
getTime1();
getTime2();
function getTime1() {
var time = getTimer();
for (var i:Number = 0; i < 1e+5; i++) {
test1();
}
trace("test1调用次数:" + test1());
trace("普通函数模式:" + (getTimer() - time));
}
function getTime2() {
var time = getTimer();
for (var i:Number = 0; i < 1e+5; i++) {
test2();
}
trace("test2调用次数:" + test2());
trace("惰性函数模式:" + (getTimer() - time));
}
[/code]
在我的机器上的测试结果是普通函数模式运行10万次的时间为825ms左右,惰性函数模式则为790ms左右。从效率上来看,2种模式基本差不多,但惰性模式有它的优点:省略了多余的全局变量num,而且可以防止变量num在函数外部被修改,效率方面也有些提升,还是值得使用的。

然而当我想测试as3下是否也这样的时候,却得到了一个惊人结果:普通函数模式运行100万次的时间为110ms左右,惰性函数模式为320ms左右。显然有一个结论是,在as3下,这种惰性函数模式效率比普通模式低了很多,是否要应用这种函数模式就值得商榷了。但是大家看清楚刚才的测试,as2下是10万次而as3下是100万次。。。它们之间的差距我只能用天壤之别来形容了。呵呵,看到这里,是不是让大家更有信心投入到as3的怀抱中呢?

FlashTail:简单实用的actionscript调试工具

08月 27th, 2007 | No Comments , 129 views | Posted by flashlizi in Flash CS3/AS3

Flash player的debuger版本有个功能,可以把flash文件中的trace信息输出到一个名为flashlog.txt的文本文件中,而且不管当前运行的flash所在的域如何或者是嵌在其他应用程序中,这些trace信息一律都会被记录在flashlog.txt中。因此我们可以利用这一特性,调试其他flash调试工具无法调试的flash程序。

首先要确认你的机器里安装了Flash player的debuger版本,检测办法:访问这里,右键点击中间那个flash(文字:Adobe Flash Player is installed.),如果在右键菜单中有“debuger”或者“调试器”的选项,则说明你已经安装了debuger版本。一般的如果你安装了flash 8或者flash cs3的话,都会自动安装了debuger版本。

接下来,新建一个mm.cfg文件。地址为:C:\Documents and Settings\username\mm.cfg,其中username为你的XP系统用户名,比如Administrator。打开mm.cfg,输入:

ErrorReportingEnable=0
TraceOutputFileEnable=1

然后,创建一个flashlog.txt文件。地址为:C:\Documents and Settings\username\Application Data\Macromedia\Flash Player\Logs\flashlog.txt,其中Logs目录需要自己创建的。这样,你机器上的flash文件里的trace信息就会保存在此文件中。但是,需要注意的是此文件只会保存最后打开的flash文件的trace信息。

为了使用方便,我做了一个监控和读取flashlog.txt文件内容的小工具:FlashTail。在你调试的时候,只要先把它打开,然后再打开需要调试的flash,FlashTail中就会把你的trace信息都显示出来。简单又非常方便,无需像其他debuger工具那样要在flash中添加调试代码,只需简单的trace()就OK!

AS3的一些优化计算方法

08月 13th, 2007 | 1 Comment , 148 views | Posted by flashlizi in Flash CS3/AS3

今天在John Grden的Blog上看到一篇关于AS3优化计算的文章:Optimizations for AS3 calculations,觉得不错,把其中的一些方法记录下来。

1、用乘法来代替除法(当除数可转化为有限数的时候)。比如var n:Number = value *0.5;要比var n:Number = value / 2;快。但差别并不是很大。只有在需要大量计算情况下,比如3D引擎中差别才比较明显。

2、用位运算代替除2或乘2。比如10>>1要比10*2快,而10<<1要比10*2快。从测试来看位运算几乎比乘除快一倍,但是一般情况下,我们不能选择位运算,比如我们就不能用13>>1来代替13/2,尽管前者比后者运算速度更快,但2者的运算结果却不一样。所以还是要看具体情况。

3、用unit()或int()代替取整运算Math.floor()和Math.ceil()。比如var test:uint = uint(1.5);要比var test:Number = Math.floor(1.5);快;而var test:uint = uint(1.5)+1;要比var test:Number = Math.ceil(1.5);也快。如果是Math.floor(),还可以用位运算(>>0)来代替。比如var test:uint =1.5>>0,比unit()或int()更快。

4、用乘-1来代替Math.abs()方法。比如var nn:Number = -23;var test:Number= nn < 0 ? nn * -1 : nn;要比var nn:Number = -23;var test:Number = Math.abs(nn);快。

当然还有更多的优化计算的方法。一般来说,低级运算要比高级运算速度;内部方法比调用其他方法速度快。另外要注意的是,这些方法有的时候可能并一定适用。

附上测试代码:
[code]import flash.utils.getTimer;
var time:Number = getTimer();
function runDivisionTest():void {
time = getTimer();
for (var i:Number=0; i<10000000; i++) {
var test:Number = i/2;
}
trace("DivisionTest: ", (getTimer()-time));
}
function runMultTest():void {
time = getTimer();
for (var i:Number=0; i<10000000; i++) {
var test:Number = i*.5;
}
trace("MultTest: ", (getTimer()-time));
}
function runBitTest():void {
time = getTimer();
for (var i:int=0; i<10000000; i++) {
var test:int = i>> 1;
}
trace("BitTest: ", (getTimer()-time));
}
function runFloorTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = 1.5;
var test:Number = Math.floor(n);
}
trace("FloorTest: ", (getTimer()-time));
}
function runUintTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = 1.5;
var test:uint = uint(n);
}
trace("UintTest: ", (getTimer()-time));
}
function runCeilTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = 1.5;
var test:Number = Math.ceil(n);
}
trace("CeilTest: ", (getTimer()-time));
}
function runUintCeilTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = 1.5;
var test:uint = n == uint(n) ? n : uint(n)+1;
}
trace("UintCeilTest: ", (getTimer()-time));
}
function runABSTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = -1.5;
var test:Number = Math.abs(n);
}
trace("ABSTest: ", (getTimer()-time));
}
function runABSMultTest():void {
time = getTimer();
for (var i:uint=0; i<10000000; i++) {
var n:Number = -1.5;
var test:Number = n <0 ? n * -1 : n;
}
trace("ABSMultTest: ", (getTimer()-time));
}
runDivisionTest();
runMultTest();
runBitTest();
runFloorTest();
runUintTest();
runCeilTest();
runUintCeilTest();
runABSTest();
runABSMultTest();[/code]

AS2:让flash捕获用户的快捷键动作

08月 10th, 2007 | No Comments , 129 views | Posted by flashlizi in Flash8/AS2

一般情况下,大家都知道要让flash捕获用户的按键动作可以使用Key类中的onKeyDown、onKeyUp事件以及Key.isDown()、Key.getCode()和Key.getAscii()等方法来实现。这里说一下如何捕获一些组合键(如ctrl+s)?下面是一段捕获ctrl+s快捷键的AS2代码:
[code]var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
trace(Key.getCode());
if (Key.isDown(Key.CONTROL) && Key.getCode() == 83) {
txt.text = "ctrl+s";
}
};
Key.addListener(keyListener);[/code]
在上面代码中,当用户按下ctrl+s快捷键的时候,文本字段txt中的文本就会变成ctrl+s,表示我们已经正常捕获ctrl+s快捷键了。注意:在flash中测试影片(ctrl+enter)的时候一定要在控制中把禁用快捷键勾上,否则测试无效。

但是有些快捷键,如ctrl+C、ctrl+F等,用上面的方法仍然无法捕获。这是因为这些快捷键已经被flash player首先给捕获做其他用途了,当然就无法传到里面的处理函数了。因此我们要告诉flash player释放这些快捷键给AS使用,幸好fscommand函数的trapallkeys命令可以实现这个目的,具体代码为:
fscommand("trapallkeys", true);

这样要实现ctrl+C快捷键,就只要在上面捕获ctrl+s快捷键的AS2代码中加上这条语句就可以了。不过注意这条语句在flash中测试影片(ctrl+enter)的时候是无效的,因为这些快捷键被flash IDE捕获,要单独运行swf文件才有效。具体代码为:
[code]fscommand("trapallkeys", true);
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
trace(Key.getCode());
if (Key.isDown(Key.CONTROL) && Key.getCode() == 67) {
txt.text = "ctrl+c";
}
};
Key.addListener(keyListener);[/code]

Function类的call方法的深入研究

08月 3rd, 2007 | No Comments , 121 views | Posted by flashlizi in Flash CS3/AS3

从as1,2开始Function类就有call和apply2个方法了。相信大家对这2个方法的应该有一些了解,这2个方法的第一个参数thisObject在有些时候很有用,合理利用他们可以使函数表现得像另一个对象的方法,而不将函数存储在该对象中。
比如官方帮助中的一个例子:
[code]
function myObject() {
}
function myMethod(obj) {
trace("this == obj? " + (this == obj));//trace() 语句将显示:this == obj? true

}
var obj:Object = new myObject();
myMethod.call(obj, obj);
[/code]

但是到了as3,this始终指向函数所属的对象。上面的例子在as3中是不成立的。那是不是说call方法中的thisObject在as3中失去了意义了呢?下面的例子说明在某些情况下还是有他的用处的:
这是一个documentClass:
[code]
package {
import flash.display.Sprite;
public class FunctionCallExample extends Sprite {
public function FunctionCallExample() {
var test1=new TestA();
var test2=new TestB();
//不管传入对象X的function的call的参数指向任何对象,
//function中的this永远都指向原对象X。
test1.callA.call(this);
//如果给callB传入的参数是一个对象X中已定义的方法,
//那么这个方法中的this永远都指向此对象X。
test2.callB(test1.callA);
//当给CallB传入的参数是一个不知所属的function的时候,
//此时这个function中的this才会由call中指向的对象来确定。
test2.callB(function(){trace(this)});
}
}
}
internal class TestA {
public function callA() {
trace(this);
}
}
internal class TestB {
public function callB(fn:Function) {
fn.call(this);
fn.call(TestA);
}
}
[/code]

通过上面的测试,我们发现,只有当function不知所属(即在参数中定义的函数)的时候,其中的this才会受call方法的thisObject参数控制。其他时候function中的this一律指向他所属的对象或类。同样的,apply方法也类似。

wow gold wow gold wow gold wow power leveling wow power leveling wow power leveling nike shoes nike shoes nike shoes nike shoes jordan shoes Jordan shoes jordan shoes Jordan shoes world of warcraft gold world of warcraft gold Replica handbags 1