そのようなツールを見つけて、うまく使いましたか?
9 に答える
AS 用のプロファイラーも探していましたが、FlashDevelop と Flex SDK で動作するフリーウェア/オープン ソース ソリューションが必要でした。何も見つかりませんでした。そこで、単純な Python スクリプトと、さらに単純な AS クラスを作成しました。このスクリプトは基本的に任意の AS ファイルを取得し、プロファイリング コード (つまり、その関数の合計ランタイムを 1 ミリ秒の精度 (呼び出しの分解能) で測定するためのflash.utils.getTimer()
呼び出し) を各関数定義に追加します。スクリプトは時々間違いを犯しますが、通常は手作業で簡単に修正できます。次に、手動でもう 1 行追加する必要があります。ある時点でプロファイリング統計をどこかにダンプします。この方法は明らかに正確とは言えませんが、それでもコードのボトルネックを十分に把握できます。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()
どちらも自由に使用、配布、改変してください。
アドビは最近、AdobeScoutと呼ばれるFlash用の新しいプロファイリングツールをリリースしました。
http://gaming.adobe.com/technologies/scout/
これは、古いFlash Builderプロファイラーを大幅に改善したものです。ActionScriptの実行と、レンダリングやネットワークなどの内部プレーヤー機能の両方について、CPU時間の詳細な内訳を提供します。
試用期間中は無料です。無料のCreativeCloudアカウントに登録するだけです。その後、無料のベーシックバージョンが引き続き提供され、フルバージョンは有料のCreativeCloudアカウントの一部として利用できます。
Flex Builder 3 に付属のプロファイラーを使用しましたが、ある程度の成功を収めています。メモリ リークや GC の問題を見つけるのに特に役立つことがわかりました。
問題のアプリケーションの非同期性と、[onEnterFrame] およびその他の内部メソッドに与えられる時間の長さのために、time-in-method パフォーマンスの領域ではあまり役に立ちませんでしたが、それでもいくつか作成することはできました。出力に基づく最適化。
Flash Player の実装はプラットフォームごとに異なり、ブラウザごとにある程度異なることに注意することが重要です。そのため、顕著な速度の違いが予想されます。そのため、リソースを集中的に使用するアプリケーションを開発している場合は、ターゲットとする各 OS に固有のプロファイリング ツールを使用する必要があります。たとえば、OS X のInstrumentsなどで、もちろん各ブラウザーでパフォーマンスをテストする必要があります。
これは私の個人的なお気に入りです。Java とオープン ソースに基づいて構築されていることに注意してください。 http://github.com/bengarney/PBLabsProfiler
フラッシュ/フレックス コンパイラの文書化されていない機能を使用します。Flash Builder 組み込みプロファイラーが使用するものと同じもの。はい!これを使用して、フラッシュ コードの一部を最適化することに成功しました。
少し前に flasm に基づいたフラッシュ プロファイラーを作成しました ( http://snow.prohosting.com/bensch/flasp.html ) flasm を使用してプロファイリング asm を挿入し、プログラムを実行する必要があります。
別の (おそらく) より良い方法は、flasm をまったく必要としない David Chang のプロファイリング コードを使用することです。www.nochump.com/asprof/
乾杯
The Minerは非常に便利で、非商用プロジェクトでは無料です。幅広い機能がありますが、「Performance Profiler」というラベルの付いたタブが最も役に立ちました。コード内のボトルネックを見つけたり、少なくとも主な原因 (レンダリング、テキスト、ネットワークなど) を知るのに最適な方法だと思います。
インストール手順を見つけるのに少し時間がかかりましたが、とても簡単です。プロジェクトに .swc ファイルを含め、ドキュメント クラス コンストラクターに 1 行のコードを追加します。
this.addChild(new TheMiner(true));
Flex Builder 3 には、パフォーマンスとメモリのプロファイラーが含まれています。私はそれを使用していませんが、それはかなりおしゃれに見えます。Flex 以外のコンテンツに使用できるかどうかはわかりませんが、AS3 でのみ機能することは間違いありません。
それとは別に、私は何年にもわたって、特定のレベルのプロファイリングのための実行可能な方法をいくつか見つけてきました。最も簡単な方法として、明らかに FPS メーターを作成し、その動作を観察することができます。コードの多いアプリケーションの詳細についてはgetTimer()
、メソッドの最初と最後で呼び出しを行い、累積時間を追跡するための単純なフレームワークを作成することを行っていますが、そのために事前に作成されたツールを使用したことはありません。 . 実際には、通常、コードが重い作業のボトルネックがどこにあるかはかなり明白です。そのような場合、最適化しようとしているものの周りにタイマーを直接配置します。
ボトルネックがレンダリングにある場合、最初に試みることは、ターゲット FPS でパブリッシュし、FPS メーターを使用して、実際の再生が (ターゲット ハードウェアで) それを下回ったときを追跡することです。たとえば、 を呼び出す 1 ミリ秒のタイムアウトを呼び出しrefreshAfterUpdate
、更新間の実際の時間を監視することで、レンダリングに関するより詳細な情報を取得できます。残念ながら、「更新ごと」よりも細かくすることはできません.ラスタライズや合成などに費やされた時間を直接見ることはできません.ラスター化をテーブルから外し、結果を観察するために、ベクトルが重いオブジェクトで。)
FlashPreloaderProfiler があります: http://jpauclair.net/flashpreloadprofiler
これは actionscript で書かれており、バックグラウンドで実行される Java アプリケーションを必要とせず、Memory Profiler のようないくつかの機能を備えています。
しかし、私は PBLabsProfiler も好みます :)