0

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

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

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

我最终打电话PerformanceProfiler.show()来获取trace稍后的电话结果。

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

对于我的需要,这可以解决问题。

然而,我想要的是避免整个"updatePlayer"事情,因为它是重复的。事实上,我想完全摆脱startandstop调用。

我的想法是用某种匿名函数来调用它,类似于(对不起,我不确定该功能的确切语法):

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

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

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

{ updateEnemies(地图, 玩家); } - 5126

...

那么,有没有办法将匿名方法的内容作为字符串获取呢?这太棒了。不过,如果您对我的问题有更简单的解决方案,我将不胜感激,因为我们现在无法发现帧速率下降,并且不想浪费时间优化可能只需要 1%的处理时间。

总之,我想要的是:

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

非常感谢您宝贵的时间。

4

3 回答 3

3

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

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

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
    }
}
于 2012-10-04T06:49:20.200 回答
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

添加到您的项目中非常容易,并且已经拥有所有这些示例/配置文件

于 2012-10-04T12:48:21.213 回答
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()在第一次遇到对象时对它执行 a 操作,并取出它的所有功能。然后,该profile函数获取我们想要的 - 我们检查缓存以获取正确的名称,然后调用它。

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

您需要对其进行返工,以便describeType()唯一适用于类,而不适用于对象(就好像您有 10 个 Sprite,它将执行 10describeType()秒)。如果您这样做,则m_functions需要为每个对象设置字典,否则(func in dict)如果您明白我的意思,那么除了第一个对象之外的所有对象实例的检查都将失败。

无论如何,你明白了:D

于 2012-10-05T09:46:14.810 回答