闪光/动作脚本CPU分析器 [英] Flash / Actionscript CPU profiler

查看:213
本文介绍了闪光/动作脚本CPU分析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你有没有发现这样的工具,并成功地用它?

Have you found such a tool and used it successfully?

推荐答案

我也一直在寻找一个分析器用于AS,但我想要一个免费/开源的解决方案,具有的FlashDevelop和Flex SDK的作品。我没有发现。所以我写了一个简单的Python脚本和一个更简单的AS类。该脚本主要采取任何文件和分析增加了code(即调用来衡量该函数的总运行时间为1毫秒的精度 - 在 flash.utils.getTimer()的分辨率调用)每个函数的定义。该脚本有时会犯错,但这些通常很容易用手工修复。然后,你需要手动添加下一行:地方倾倒在某一点上分析统计。这种方法是准确的显然远,但它仍然给你的瓶颈良好的感觉在你的code。我用了一个100K的文件,成功。

I was also looking for a profiler for AS, but I wanted an freeware/open source solution that works with FlashDevelop and Flex SDK. I found none. So I wrote a simple python script and an even simpler AS class. The script essentially takes any AS file and adds profiling code (i.e. calls to measure the total runtime of that function with an accuracy of 1 ms - the resolution of the flash.utils.getTimer() call) to each function definition. The script sometimes makes mistakes, but these are usually easy to fix by hand. Then you need to add one more line manually: dump the profiling statistics somewhere at some point. This method is obviously far from accurate, but it nonetheless gives you good feel of bottlenecks in your code. I used it for a 100k file with success.

下面是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脚本:

And here is the python script that does the trick:

import sre, sys

rePOI = sre.compile(r'''\bclass\b|\bfunction\b|\breturn\b|["'/{}]''')
reFun = sre.compile(r'\bfunction\b\s*((?:[gs]et\s+)?\w*)\s*\(')
reCls = sre.compile(r'class\s+(\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('return\s*;', 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()

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

Feel free to use, distribute and modify both.

这篇关于闪光/动作脚本CPU分析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆