衡量代码执行的各个阶段

时间:2011-08-12 00:23:20

标签: flex

有没有办法衡量我的代码运行所需的平均时间以及为Flex应用呈现的每个帧?更具体地说,我知道如何使用getTimer(),但我不确定为了做到这一点我应该听哪些事件。我正在阅读this post并且不确定你是如何弄清楚实际渲染花了多长时间(似乎可能是RENDER事件触发和下一个ENTER_FRAME事件触发之间的时间,但我是不确定)。此外,不确定用户代码的位置,或者我是否应该关心EXIT_FRAME和FRAME_CONSTRUCTED。

非常感谢任何帮助!

编辑----

这里有一段代码,显示了超级简单的灵活应用中第二帧重复的主要事件。我想弄清楚的是,经典Flex赛道的“用户代码”和“渲染”部分之间是否存在明确的关系,以及我追踪的四个主要信号之间的间隔。

代码:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import flash.utils.getTimer;

            public var t:Timer;
            protected function button1_clickHandler(event:MouseEvent):void
            {
                t = new Timer(40, 50);
                t.addEventListener(TimerEvent.TIMER, handleTimeTick);
                t.addEventListener(TimerEvent.TIMER_COMPLETE, timerDone);
                addEventListener(Event.RENDER, application1_renderHandler);
                addEventListener(Event.ENTER_FRAME, application1_enterFrameHandler);
                addEventListener(Event.EXIT_FRAME, application1_exitFrameHandler);
                addEventListener(Event.FRAME_CONSTRUCTED, application1_frameConstructedHandler);
                t.start();
            }

            protected function handleTimeTick(e:TimerEvent):void
            {
                shape.x += 5;
            }

            protected function timerDone(e:TimerEvent):void
            {
                t.stop();
                t.removeEventListener(TimerEvent.TIMER, handleTimeTick);
                t.removeEventListener(TimerEvent.TIMER_COMPLETE, timerDone);
                removeEventListener(Event.RENDER, application1_renderHandler);
                removeEventListener(Event.ENTER_FRAME, application1_enterFrameHandler);
                removeEventListener(Event.EXIT_FRAME, application1_exitFrameHandler);
                removeEventListener(Event.FRAME_CONSTRUCTED, application1_frameConstructedHandler);
            }

            protected function application1_renderHandler(event:Event):void
            {
                trace("render fire", getTimer());
            }

            protected function application1_enterFrameHandler(event:Event):void
            {
                trace("enter frame fire", getTimer());
            }

            protected function application1_exitFrameHandler(event:Event):void
            {
                trace("exit frame fire", getTimer());
            }

            protected function application1_frameConstructedHandler(event:Event):void
            {
                trace("frame constructed fire", getTimer());
            }

        ]]>
    </fx:Script>


    <s:Rect id="shape" x="0" y="0" height="20" width="20">
        <s:fill>
            <s:SolidColor color="0xff0000"/>
        </s:fill>
    </s:Rect>

    <s:Button x="10" y="100" click="button1_clickHandler(event)" label="go"/>
</s:Application>

3 个答案:

答案 0 :(得分:2)

测试“框架”运行所需时间的简便方法。这是一个简单的例子。这是未经测试但你明白了。您还应该查看Grant Skinners talk about performance和帧率。

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" 
               xmlns:parsley="http://www.spicefactory.org/parsley"
               creationComplete="onCreationComplete()">
    <fx:Script> 
        <![CDATA[
            private var _timer:Timer = new Timer(1000);
            private var _previousTime:int;
            private var _avgTime:int;
            private var _times:Array = [];

            private function onCreationComplete():void
            {
                // Add event listener for enter frame
                this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
                // Listen to timer
                this._timer.addEventListener(TimerEvent.TIMER, onTimer);
                // start timer
                this._timer.start();
            }

            private function onEnterFrame(e:Event):void
            {
                var time:int = getTimer() - this._previousTime;
                trace("timer frame took "+ time +"ms");
                this._previousTime = getTimer();
                this._times.push(time);
            }   

            private function onTimer(e:Event):void
            {
                var total:int = 0;
                for(var i:uint = 0, len:uint = this._times.length; i < len ; i++)
                {
                    total += this._times[i];
                }
                this._avgTime = total/len;
                this._times = [];

                trace("Average frame time is "+ this._avgTime +"ms");
            }
        ]]>
    </fx:Script>
</s:Application>

答案 1 :(得分:1)

任何Flex应用只有两帧。第一帧是框架的启动/初始化,第二帧是你的应用程序。

framerate在Flex Application标记上设置,默认值为每秒24帧。因此,需要Flex 1/24秒来渲染应用程序的帧。

但是,完全可能是您的代码需要执行多个帧,我相信这就是您要测量的内容。

对于某些背景阅读,您应该调查Flex Elastic Racetrack有关Flex如何为不同类型的处理划分每个帧的信息。

然后,如果您还没有,请阅读Flex Component LifeCycle。 (Flex 3 Version)。

您已经提到了getTimer()方法。要点是在两点使用getTimer()并比较这两个值。这两点是完全取决于你想要衡量的。

如果要测量Flex组件完成启动过程所需的时间,请在创建它之前使用getTimer()(AKA new Component()),然后在该组件的creationComplete事件的侦听器中使用。

如果您想要对完整的应用程序设置进行计时,最好的办法是在主应用程序标记的preinitialize事件处理程序中获取值,并在applicationComplete处理程序中获取值。标签

这有帮助吗?

答案 2 :(得分:0)

好的,在网上阅读了很多内容后,我认为this presentation提供了有关如何衡量弹性赛道时间的最佳信息(请参阅演示文稿中的this piece of code)。