Flash/Actionscript CPU探查器
您是否找到了这样的工具并成功地使用了它?Flex Builder 3包含一个。我没用过,但它看起来很时髦。我不确定它是否可以用于非Flex内容,但它肯定只适用于AS3 除此之外,这些年来,我已经找到了一些可行的方法来进行一定程度的分析。在最简单的情况下,你显然可以建立一个FPS米,并观察它的行为。有关代码密集型应用程序的更多信息,我做过的一件事是创建一个简单的框架,用于在方法的开始和结束时调用Flash/Actionscript CPU探查器,flash,actionscript,profiling,cpu-usage,Flash,Actionscript,Profiling,Cpu Usage,您是否找到了这样的工具并成功地使用了它?Flex Builder 3包含一个。我没用过,但它看起来很时髦。我不确定它是否可以用于非Flex内容,但它肯定只适用于AS3 除此之外,这些年来,我已经找到了一些可行的方法来进行一定程度的分析。在最简单的情况下,你显然可以建立一个FPS米,并观察它的行为。有关代码密集型应用程序的更多信息,我做过的一件事是创建一个简单的框架,用于在方法的开始和结束时调用getTimer(),并跟踪累计时间,但我从未为此使用过任何预制作的工具。在实践中,对于代码繁重的工作来
getTimer()
,并跟踪累计时间,但我从未为此使用过任何预制作的工具。在实践中,对于代码繁重的工作来说,瓶颈通常非常明显,在这些情况下,我只是将计时器直接放在我试图优化的内容周围
当渲染中出现瓶颈时,首先要尝试的是以目标FPS进行发布,并使用FPS计跟踪实际播放低于该值的时间(在目标硬件上)。例如,通过调用调用
refreshAfterUpdate
的1ms超时,以及监视刷新之间的实际时间,可以获得有关渲染的更详细信息。不幸的是,你不能得到比“每次刷新”更精确的结果——你不能直接看到光栅化、合成等所花费的时间(尽管你经常可以推断出这些事情。例如,你可以在向量重的对象上启用位图缓存,使光栅化从表中消失,并观察结果)需要注意的是,Flash Player的实现在每个平台上都是不同的,在某种程度上每个浏览器都是不同的,因此需要注意速度上的显著差异。因此,如果您正在开发一个资源密集型应用程序,您应该使用特定于您所针对的每个操作系统的评测工具,例如在OS X上,当然还要测试每个浏览器的性能。我使用了Flex Builder 3附带的评测器,并取得了一定的成功。我发现在查找内存泄漏和/或GC问题时特别有用
虽然我仍然能够根据输出进行一些优化,但由于所讨论的应用程序的异步性质以及[OneInterFrame]和其他内部方法所花费的时间,它在方法性能方面对我的用处要小得多。我还在寻找AS的分析器,但我想要一个与FlashDevelop和FlexSDK一起工作的免费/开源解决方案。我没有找到。所以我编写了一个简单的python脚本和一个更简单的AS类。该脚本实质上将任何函数作为文件,并向每个函数定义中添加分析代码(即以1ms的精度测量该函数的总运行时间的调用-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()
导入sre,系统
rePOI=sre.compile(r'''\b类\b | \b函数\b | \b返回\b |['/{}]'')
REUN=sre.compile(r'\b函数\b\s*((?:[gs]et\s+)\w*)\s*\('))
reCls=sre.compile(r'class\s+(\w+[\s{]'))
rest=sre.compile(r''([“'/])。(?我不久前基于flasm编写了一个flash分析器(),您需要使用flasm插入评测asm,然后运行程序
另一个(也许)更好的方法是使用David Chang的评测代码,它根本不需要flasm/
干杯这是我个人最喜欢的。
请注意,它是基于java和开源构建的。
它使用flash/flex编译器的未记录特性。
与Flash Builder内置探查器使用的相同。
是的!我已经成功地使用它优化了我的一些flash代码。有一个FlashPrederProfiler:
它是用actionscript编写的,不需要在后台运行java应用程序,并具有一些其他功能,如内存分析器
但我也更喜欢PBLabsProfiler:)我发现它非常有用,而且对非商业项目是免费的。它有很多功能,但标签为“性能分析器”的选项卡最有帮助。我发现它是一种很好的方法,可以发现代码中的瓶颈,或者至少知道主要原因是什么(渲染、文本、网络等…)
我花了一点时间才找到安装说明,但非常简单。在项目中包含.swc文件,然后在文档类构造函数中添加一行代码
this.addChild(new TheMiner(true));
更多信息:Adobe最近发布了一款新的Flash评测工具,名为Adobe Scout:
这是对旧的Flash Builder profiler的巨大改进-它提供了CPU时间的详细分解,包括ActionScript执行以及渲染和联网等内部播放器功能
试用期是免费的-你只需要注册一个免费的创意云帐户。之后,将继续提供免费的基本版本,完整版本作为付费创意云帐户的一部分提供。链接指向Flex Builder 3功能介绍-这不是当前版本吗?哇,你说得对-你可以看出我不是FB用户。为了清楚起见,我将进行编辑,但也许更熟悉FB探查器的人可以添加有关输入和输出的信息。感谢您的帮助!我在python脚本的第31行收到一个错误:UnboundLocalError:在赋值之前引用的局部变量“klass”我在函数的开头添加了一行初始化klassn、 @DavidHanak请提供如何使用您的工具的说明,以便新手使用。谢谢。是的,按钮实验室探查器完成了这项工作