AS3 - 将表达式转换为字符串

时间:2012-10-04 06:23:57

标签: actionscript-3 flash profiling type-conversion

有没有办法将AS3中的表达式转换为字符串?

我正在为我的Flash AS3文件制作一个非常小规模的分析器来找到瓶颈,这是当前的语法(这很乏味):

PerformanceProfiler.start("updatePlayer");
updatePlayer(map, enemies);
PerformanceProfiler.stop();

我最终打电话给PerformanceProfiler.show()以便稍后通过trace电话获取结果。

在内部,PerformanceProfiler将通过函数名称(例如"updatePlayer")链接的字典保存到传递给它的总毫秒数列表中。 show函数仅列出函数名称以及每个函数的总时间。

根据我的需要,这可以解决问题。

然而,我想要避免整个"updatePlayer"事,因为它是重复的。事实上,我想完全摆脱startstop来电。

我的想法是用某种匿名函数来调用它,这有点像(抱歉,我不确定该功能的确切语法):

PerformanceProfiler.profile( { updatePlayer(map, enemies); } );

并且只会以这种方式显示结果:

  

{updatePlayer(地图,敌人); } - 1202

     

{updateEnemies(map,player); } - 5126

     

...

那么,有没有办法将匿名方法的内容作为字符串?这太棒了。但是,如果你对我的问题有一个更简单的解决方案,我会真的很感激,因为我们现在无法看到帧速率下降,并且不想浪费时间来优化可能只需要1%的时间处理时间。

总之,我想要的是:

{ updatePlayer(map, enemies); }在AS3中转换为"{ updatePlayer(map, enemies); }"

非常感谢你宝贵的时间。

3 个答案:

答案 0 :(得分:3)

我认为没有简单的方法可以做到这一点并知道在没有探查器的情况下调用了哪些函数。

但您可以使用'Error'和'arguments'创建读取Namespace.Class.Function名称和检查参数的函数:

public function someFunction (param1:Object , param2:Object ):void {
   Profile(arguments);
   // function body ...
}

////////

public function Profile (args:Object):void {
    trace(new Error().getStackTrace()); // from this string You will read func name
    for each(var o:* in args) {
    trace("param:",o); // here are parameters
    }
}

答案 1 :(得分:1)

虽然它没有完全回答您的问题,但请查看flash.sampler包:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/sampler/package-detail.html

使用它,你根本不需要调用PerformanceProfiler,你只需要解析返回的样本。

如果您想快速了解它,请查看矿工:http://www.sociodox.com/theminer/index.html

添加到您的项目非常容易,并且已经有所有这些样本/分析

答案 2 :(得分:0)

另一个答案,因为为什么不是:)

package  
{
    import flash.display.Sprite;
    import flash.system.System;
    import flash.utils.describeType;
    import flash.utils.Dictionary;
    import flash.utils.getTimer;

    public class TestDescribeType extends Sprite
    {
        private var m_cache:Dictionary      = null; // a cache that says if we've used this object before
        private var m_functions:Dictionary  = null; // the functions for this object

        public function TestDescribeType() 
        {
            this.m_cache        = new Dictionary;
            this.m_functions    = new Dictionary;

            this.profile( this, this.one );
            this.profile( this, this.two, 4.5 );
            this.profile( this, this.three, 4.5, "hello" );
            this.profile( this, this.four, 4.5, "hello" );
        }

        // profiles how long it takes a function to complete
        public function profile( obj:*, func:Function, ...params ):void
        {
            // if we don't have this object in our cache, parse it
            if ( !( obj in this.m_cache ) )
                this._parse( obj );

            // get our functions dictionary and get our function name
            var dict:Dictionary = this.m_functions[obj];
            var funcName:String = ( dict != null && ( func in dict ) ) ? dict[func] : "Unknown func";

            // start our timer and call our function
            var startTime:int = getTimer();
            func.apply( null, params );
            trace( "  " + funcName + " took " + ( getTimer() - startTime ) + "ms to finish" );
        }

        // some test functions
        public function one():void { trace( "one()" ) }
        public function two( one:Number ):void { trace( "two(" + one + ")" ) }
        public function three( one:Number, two:String ):void { trace( "three(" + one + ", " + two + ")" ) }
        public function four( one:Number, two:String, three:int = 0 ):void { trace( "four(" + one + ", " + two + ", " + three + ")" ) }

        // parses a class/object and removes all the functions from it
        private function _parse( obj:* ):void
        {
            // get our xml
            var x:XML           = describeType( obj );
            this.m_cache[obj]   = true; // we don't need to store the xml, just that we've parsed it

            // find our functions
            var funcs:Dictionary = new Dictionary;
            for each( var mx:XML in x.method )
            {
                var name:String     = mx.@name;
                var func:Function   = obj[name] as Function;

                // store the function with the name etc in our dictionary
                funcs[func] = name;
            }

            // store our functions
            this.m_functions[obj] = funcs;

            // kill our xml object immediately - helps memory
            System.disposeXML( x );
        }

    }

}

运行代码以了解它的作用。基本上,我们在第一次遇到对象时对对象执行describeType(),并取出它的所有功能。然后,profile函数采用我们想要的 - 我们检出缓存以获得正确的名称,然后调用它。

比在对象上抛出错误(初始describeType())更快的优点是有点慢,但它是一次性的,如果你真的想要你可以添加一个预处理步骤到。

你需要重做它,以便describeType()仅适用于类,而不是对象(就像你有10个精灵,它会做10 describeType())。如果你这样做,那么每个对象需要设置m_functions字典,否则(func in dict)检查对于除第一个对象之外的所有对象实例都会失败,如果你看到我的意思

无论如何,你明白了:D