11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 1820|回复: 1
上一主题 下一主题

[日期 & 时间 & 计时器] 时间效率,Timer和EnterFrame在FP 10.1之后测试和建议

[复制链接] TA的其它主题
发表于 2019-4-20 13:03:52 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
转载:

关于Timer还是EnterFrame的选择,一直是很多AS3开发者讨论的话题, 随着10.1即将普及,我这次对10.1的Timer和EnterFrame进行了一次较详细的测试,给大家在他们的选择和使用上做些参考。

注:flashplayer10.1新增了一个当前窗口在非激活状态下会自动降低fps到2fps来节省cpu消耗,这将直接影响靠fps驱动的enterframe的效率和准确性。

测试环境主要以网页下的flash执行效率为主, 分为空运算和重运算,同时运行和分别运行。

FPS为25(大多数应用的默认值), 即40ms间隔,发布统一选择以10.1发布。

为了避免因为频繁trace或频繁写入场景txt受到影响,我设定了间断式的输出结果来保证结果的纯洁。

(测试代码见楼底)
1. 独立Timer 运行,即40毫秒的timer,更新时无任何运算。

测试结果如下:
01.jpg
结论:从结果上看, Timer在网页中难以稳定运行在40ms, 但貌似相对稳定的运行在65和70之间切换。


2. 独立Timer 运行 , 在上面的基础上增加最小化当前窗口和切换到其他tab页中的操作。

02.jpg
结论:如图所见,Timer同样被10.1的新增自动降fps功能影响,会被限制到2fps。

3. EnterFrame独立运行,25fps,更新时无任何运算。

03.jpg
结论: 比Timer更准确,但 除了刚开始的1秒钟,之后的fps并不是稳定在40的, 而是在35和50之间切换,但至少是围绕着40ms。

4. EnterFrame的降fps和Timer的相同,都是500ms, 2fps。 这个就不贴图了。

5. 因为无运算时Timer比Enterframe时间效率要差一些,以至于独立的Timer重运算普遍都比EnterFrame的耗时要偏长。

6. 独立Timer,改为 100ms 和 110ms的测试。

04.png
结论:Timer 在100毫秒跑的非常精确,经过测试,可以达到精确的值必须是100的倍数,即100,200,300... 右图为110ms对比,可以看到非常的诡异。 这个在pc和mac测试结果都差不多,pc上更精确,mac略有偶尔的数值抖动。

7. Timer使用空运算,EnterFrame使用重运算,同时运行,顺序是Timer在前。

05.png
结论: 我们发现,由于enterframe中使用了重运算,timer即便是在更新时,由于得不到cpu时间,并不会被执行,而是等enterframe执行结束后,timer再执行,并且由于是空操作,所以timer和enterframe返回的时间是同样的。

8. 为了进一步证实第七点结论,又做了两组实验:1)timer以40ms和enterframe的10fps(100ms), 2)让timer以100ms,enterframe是25fps。

结论:两组实验都完全输出enterframe在前的顺序,并且timer和enterframe的时间都一致,所以可以证实因为enterframe效率优于timer,timer总是在enterfame之后才会更新,在enterframe执行重运算时,  timer会得不到cpu时间。

9. Timer重运算,EnterFrame空运算,fps一致。

结论:由于以上论证,再加上Timer内有重运算,enterframe依然会被先执行,并且Timer的速度会受到进一步影响,时间经常无法和EnterFrame同步,只能勉强跟上。

写了这些实验,对Timer和EnterFrame的使用上有一些建议:

1. EnterFrame是恒定的,稳定的,比较适合用来更新渲染画面,如Tween。 但不适合做异步计算和处理, 如果能保证cpu每帧的计算效率在40ms以内,可以把计算放到enterframe时序中,这样可以稳定25fps,当然,这不包括渲染损耗。


2. Timer在100ms的倍数是很稳定的,pc和mac都能稳定,非100的倍数的值会有两个相差不大的值交替出现。


3. EnterFrame在12、20、30fps都比25fps更稳定,25fps会有两个相差不到大的数值交替出现。


4. EnterFrame在计算时优于Timer。


5. Timer更适合使用异步的长周期来改变数据的状态,并不适合短时间持续更新数据,或是渲染画面。


6,EnterFrame和Timer同样受到非活动创口的fps自动降低的影响。


7. 当受到影响时,无法通过判断frameRate==2,使用一个延迟时间,判断出正好500ms的延迟(2fps),并在相应的enterframe中做切换特殊处理,在2fps中要完成原正常fps的渲染结果才能避免渲染的延迟影响。





测试代码:(代码中的函数注释和数值可微调即可实现上面的测试结果)
[Actionscript3] 纯文本查看 复制代码
package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.utils.Timer;
 
    /**
    * ...
    * @author Demon.S
    */
    public class Main extends Sprite
    {
        private var timerDelay:Number;
        private var enterDelay:Number;
        private var txt:TextField;
        private var log:String;
        public function Main ():void
        {
            if (stage)
            {
                init ();
            }
            else
            {
                addEventListener (Event.ADDED_TO_STAGE, init);
            }
        }
 
        private function init (e:Event = null):void
        {
            removeEventListener (Event.ADDED_TO_STAGE, init);
            //init
            txt = new TextField();
            txt.width = 500;
            txt.height = 500;
            addChild (txt);
            log = "";
            //test suit
            //  testTimer();
            testEnterFrame ();
        }
 
        private function testEnterFrame ():void
        {
            stage.frameRate = 25;
            this.addEventListener (Event.ENTER_FRAME, enterFrameHandler);
            enterDelay = getTimer();
 
        }
 
        private function enterFrameHandler (e:Event):void
        {
            //heavyTest();
            var t:int = getTimer() - enterDelay;
            _trace ("enter " +t );
            if (t == 500)
            {
                _trace ("fp10.1 hidden mode");
            }
            enterDelay = getTimer();
        }
 
        private function timerUpdate (e:TimerEvent):void
        {
            // heavyTest();
 
            var t:int = getTimer() - timerDelay;
            _trace ("timer " + t);
            if (t == 500)
            {
                _trace ("fp10.1 hidden mode");
            }
            timerDelay = getTimer();
        }
 
        private function testTimer ():void
        {
            var timer:Timer = new Timer(40);
            timer.addEventListener (TimerEvent.TIMER, timerUpdate);
            timerDelay = getTimer();
            timer.start ();
        }
 
        private function _trace (...arguments):void
        {
 
            //trace.apply(this, arguments);
 
            log += arguments.join() + "\n";
            if (log.length>100)
            {
                txt.appendText (log);
                txt.scrollV=txt.maxScrollV;
                log="";
            }
        }
 
        private function heavyTest ():void
        {
            for (var i:int = 0; i < 1000000; i++)
            {
                var a:Array=[];
            }
 
        }
 
    }
 
}

评分

参与人数 1银子 +20 贡献 +2 收起 理由
TKCB + 20 + 2

查看全部评分

发表于 2019-4-20 15:47:50 | 显示全部楼层
【11RIA 闪客社区,评分公示】:
是否有价值:良好(银子 +20  贡献 +2)
是否原创:否
是否翻译:否
如对自己的评分有疑问,则咨询版主、管理员等。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表