你找到这样的工具并成功使用了吗?
9 回答
我也在寻找一个用于 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()
随意使用、分发和修改两者。
Adobe 最近发布了一个新的 Flash 分析工具,称为 Adobe Scout:
http://gaming.adobe.com/technologies/scout/
这是对旧的 Flash Builder 分析器的巨大改进 - 它为您提供了 CPU 时间的详细细分,包括 ActionScript 执行以及渲染和网络等内部播放器功能。
它在试用期内是免费的 - 您只需注册一个免费的 Creative Cloud 帐户。之后,将继续提供免费的基本版本,完整版作为付费 Creative Cloud 帐户的一部分提供。
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.
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.
我使用 Flex Builder 3 附带的分析器取得了一定的成功。我发现在查找内存泄漏和/或 GC 问题时特别有用。
由于相关应用程序的异步性质以及 [onEnterFrame] 和其他内部方法的时间量,它在方法时间性能方面对我的用处要小得多,尽管我仍然能够做一些基于输出的优化。
前段时间我写了一个基于 flasm 的 flash profiler ( http://snow.prohosting.com/bensch/flasp.html ) 你需要使用 flasm 插入 profiling asm 然后运行程序。
另一种(也许)更好的方法是使用 David Chang 的分析代码,它根本不需要 flasm。www.nochump.com/asprof/
干杯
Flex Builder 3 包括一个性能和内存分析器。我没用过,但看起来很时髦。我不确定它是否可以用于非 Flex 内容,但它肯定只适用于 AS3。
除此之外,多年来,我发现了一些可行的方法来进行一定程度的分析。在最简单的情况下,您显然可以构建一个 FPS 计并观察它的行为。有关代码繁重的应用程序的更多信息,我所做的一件事是创建一个简单的框架,用于getTimer()
在方法的开头和结尾进行调用并跟踪累积时间,但我从未为此使用任何预制工具. 在实践中,代码繁重工作的瓶颈通常很明显,在这些情况下,我只是将计时器直接放在我要优化的地方。
当瓶颈出现在渲染中时,首先要尝试的是简单地以目标 FPS 发布,并使用 FPS 仪表来跟踪实际播放何时低于该值(在目标硬件上)。您可以通过调用 1ms 超时来获取有关渲染的更多详细信息refreshAfterUpdate
,并监控刷新之间的实际时间。不幸的是,您无法获得比“每次刷新”更精细的信息 - 您无法直接看到光栅化、合成等花费了多少时间。(尽管您通常可以推断出这些事情。例如,您可以启用位图缓存在矢量重的对象上取消光栅化,并观察结果。)
我发现The Miner非常有用,而且它对非商业项目是免费的。它具有广泛的功能,但标有“性能分析器”的选项卡是最有帮助的。我发现这是找到代码瓶颈的好方法,或者至少知道主要原因是什么(渲染、文本、网络等)。
我花了一点时间找到安装说明,但这很简单。在项目中包含 .swc 文件,然后在文档类构造函数中添加 1 行代码。
this.addChild(new TheMiner(true));
更多信息: http: //www.sociodox.com/theminer/support.html
有一个 FlashPreloaderProfiler:http: //jpauclair.net/flashpreloadprofiler
它是用 actionscript 编写的,不需要在后台运行 java 应用程序,并且具有更多功能,例如 Memory Profiler。
但我也更喜欢 PBLabsProfiler :)