加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flash/Actionscript CPU分析器

发布时间:2020-12-15 19:48:59 所属栏目:百科 来源:网络整理
导读:你有没有找到这样一个工具并成功使用它? 解决方法 我也在寻找AS的分析器,但是我想要一个可以与FlashDevelop和Flex SDK一起使用的免费软件/开源解决方案。我没有找到。所以我写了一个简单的python脚本和一个更简单的AS类。该脚本基本上采用任何AS文件,并添
你有没有找到这样一个工具并成功使用它?

解决方法

我也在寻找AS的分析器,但是我想要一个可以与FlashDevelop和Flex SDK一起使用的免费软件/开源解决方案。我没有找到。所以我写了一个简单的python脚本和一个更简单的AS类。该脚本基本上采用任何AS文件,并添加了分析代码(即调用以测量该功能的总运行时间,精度为1 ms,即flash.utils.getTimer()调用的分辨率)到每个函数定义。脚本有时候会出错,但这些脚本通常很容易用手修复。然后,您需要手动添加一行:在某一时刻将分析统计信息转储到某处。这种方法显然远不是准确的,但是它给你的代码带来了瓶颈的良好感觉。我用它成功的一个100k文件。

这是AS类:

package  {
    public class Profiler {
        private static var instance:Profiler;

        public static function get profiler():Profiler {
            if (!Profiler.instance) Profiler.instance = new Profiler;
            return Profiler.instance;
        }

        private var data:Object = {};

        public function profile(fn:String,dur:int):void {
            if (!data.hasOwnProperty(fn)) data[fn] = new Number(0);
            data[fn] += dur / 1000.0;
        }

        public function clear():void {
            data = { };
        }

        public function get stats():String {
            var st:String = "";
            for (var fn:String in data) {
                st += fn + ":t" + data[fn] + "n";
            }
            return st;
        }
    }
}

这里是python脚本的诀窍:

import sre,sys

rePOI = sre.compile(r'''bclassb|bfunctionb|breturnb|["'/{}]''')
reFun = sre.compile(r'bfunctionbs*((?:[gs]ets+)?w*)s*(')
reCls = sre.compile(r'classs+(w+)[s{]')
reStr = sre.compile(r'''(["'/]).*?(?<!)1''')

def addProfilingCalls(body):
    stack = []
    pos = 0
    depth = 0
    retvar = 0
    klass = ""
    match = rePOI.search(body,pos)
    while match:
        poi = match.group(0)
        pos = match.start(0)
        endpos = match.end(0)

        if poi in '''"'/''':
            strm = reStr.match(body,pos)
            if strm and (poi != '/' or sre.search('[=(,]s*$',body[:pos])):
                endpos = strm.end(0)

        elif poi == 'class':
            klass = reCls.match(body,pos).group(1)
            sys.stderr.write('class ' + klass + 'n')

        elif poi == 'function':
            fname = reFun.match(body,pos)
            if fname.group(1):
                fname = klass + '.' + fname.group(1)
            else:
                lastf = stack[-1]
                lastf['anon'] += 1
                fname = lastf['name'] + '.anon' + str(lastf['anon'])
            sys.stderr.write('function ' + fname + 'n')
            stack.append({'name':fname,'depth':depth,'anon':0})

            brace = body.find('{',pos) + 1
            line = "nvar __start__:int = flash.utils.getTimer();"
            body = body[:brace] + line + body[brace:]
            depth += 1
            endpos = brace + len(line)

        elif poi == '{':
            depth += 1

        elif poi == 'return':
            lastf = stack[-1]
            semicolon = body.find(';',pos) + 1
            if sre.match('returns*;',body[pos:]):
                line = "{ Profiler.profiler.profile('" + lastf['name'] + 
                       "',flash.utils.getTimer() - __start__); return; }"
            else:
                retvar += 1
                line = "{ var __ret" + str(retvar) + "__:* =" + body[pos+6:semicolon] + 
                       "nProfiler.profiler.profile('" + lastf['name'] + 
                       "',flash.utils.getTimer() - __start__); return __ret" + str(retvar) + "__; }"
            body = body[:pos] + line + body[semicolon:]
            endpos = pos + len(line)

        elif poi == '}':
            depth -= 1
            if len(stack) > 0 and stack[-1]['depth'] == depth:
                lastf = stack.pop()
                line = "Profiler.profiler.profile('" + lastf['name'] + 
                    "',flash.utils.getTimer() - __start__);n"
                body = body[:pos] + line + body[pos:]
                endpos += len(line)

        pos = endpos
        match = rePOI.search(body,pos)
    return body

def main():
    if len(sys.argv) >= 2: inf = open(sys.argv[1],'rU')
    else: inf = sys.stdin
    if len(sys.argv) >= 3: outf = open(sys.argv[2],'wU')
    else: outf = sys.stdout
    outf.write(addProfilingCalls(inf.read()))
    inf.close()
    outf.close()

if __name__ == "__main__":
    main()

随意使用,分发和修改两者。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读