16

你找到这样的工具并成功使用了吗?

4

9 回答 9

16

我也在寻找一个用于 AS 的分析器,但我想要一个与 FlashDevelop 和 Flex SDK 一起使用的免费软件/开源解决方案。我没有找到。所以我写了一个简单的python脚本和一个更简单的AS类。该脚本本质上采用任何 AS 文件并将分析代码(即调用以测量该函数的总运行时间,精度为 1 毫秒 -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'''\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()

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

于 2009-01-14T19:28:26.483 回答
6

Adobe 最近发布了一个新的 Flash 分析工具,称为 Adob​​e Scout:

http://gaming.adobe.com/technologies/scout/

这是对旧的 Flash Builder 分析器的巨大改进 - 它为您提供了 CPU 时间的详细细分,包括 ActionScript 执行以及渲染和网络等内部播放器功能。

它在试用期内是免费的 - 您只需注册一个免费的 Creative Cloud 帐户。之后,将继续提供免费的基本版本,完整版作为付费 Creative Cloud 帐户的一部分提供。

于 2013-01-10T23:29:23.227 回答
2

It's important to note that the Flash Player implementation is different on each platform and to an extent each browser, so expect notable speed differences. So if you're developing a resource intensive application you should be using profiling tools specific to each OS you're targeting, like for example Instruments on OS X and of course test the performance in each browser.

于 2009-01-11T17:42:06.433 回答
2

This one is my personal favorite. Note that it's built on java and open source. http://github.com/bengarney/PBLabsProfiler

It uses undocumented features of flash/flex compiler. The same ones Flash Builder built-in profiler uses. And yes! I have successfully used it to optimize some of my flash code.

于 2010-09-20T18:45:37.467 回答
2

我使用 Flex Builder 3 附带的分析器取得了一定的成功。我发现在查找内存泄漏和/或 GC 问题时特别有用。

由于相关应用程序的异步性质以及 [onEnterFrame] 和其他内部方法的时间量,它在方法时间性能方面对我的用处要小得多,尽管我仍然能够做一些基于输出的优化。

于 2009-01-12T08:41:22.077 回答
2

前段时间我写了一个基于 flasm 的 flash profiler ( http://snow.prohosting.com/bensch/flasp.html ) 你需要使用 flasm 插入 profiling asm 然后运行程序。

另一种(也许)更好的方法是使用 David Chang 的分析代码,它根本不需要 flasm。www.nochump.com/asprof/

干杯

于 2009-07-21T06:59:14.147 回答
1

Flex Builder 3 包括一个性能和内存分析器。我没用过,但看起来很时髦。我不确定它是否可以用于非 Flex 内容,但它肯定只适用于 AS3。

除此之外,多年来,我发现了一些可行的方法来进行一定程度的分析。在最简单的情况下,您显然可以构建一个 FPS 计并观察它的行为。有关代码繁重的应用程序的更多信息,我所做的一件事是创建一个简单的框架,用于getTimer()在方法的开头和结尾进行调用并跟踪累积时间,但我从未为此使用任何预制工具. 在实践中,代码繁重工作的瓶颈通常很明显,在这些情况下,我只是将计时器直接放在我要优化的地方。

当瓶颈出现在渲染中时,首先要尝试的是简单地以目标 FPS 发布,并使用 FPS 仪表来跟踪实际播放何时低于该值(在目标硬件上)。您可以通过调用 1ms 超时来获取有关渲染的更多详细信息refreshAfterUpdate,并监控刷新之间的实际时间。不幸的是,您无法获得比“每次刷新”更精细的信息 - 您无法直接看到光栅化、合成等花费了多少时间。(尽管您通常可以推断出这些事情。例如,您可以启用位图缓存在矢量重的对象上取消光栅化,并观察结果。)

于 2008-12-11T02:14:29.293 回答
1

我发现The Miner非常有用,而且它对非商业项目是免费的。它具有广泛的功能,但标有“性能分析器”的选项卡是最有帮助的。我发现这是找到代码瓶颈的好方法,或者至少知道主要原因是什么(渲染、文本、网络等)。

我花了一点时间找到安装说明,但这很简单。在项目中包含 .swc 文件,然后在文档类构造函数中添加 1 行代码。

this.addChild(new TheMiner(true));

更多信息: http: //www.sociodox.com/theminer/support.html

于 2012-01-17T05:01:06.647 回答
0

有一个 FlashPreloaderProfiler:http: //jpauclair.net/flashpreloadprofiler

它是用 actionscript 编写的,不需要在后台运行 java 应用程序,并且具有更多功能,例如 Memory Profiler。

但我也更喜欢 PBLabsProfiler :)

于 2011-03-05T22:07:16.433 回答