2008-12-10 7 views

Antwort

1

Flex Builder 3 enthält eine performance and memory profiler. Ich habe es nicht benutzt, aber es sieht ziemlich schick aus. Ich bin nicht sicher, ob es für Nicht-Flex-Inhalte verwendet werden kann, aber es wird definitiv nur für AS3 funktionieren.

Abgesehen davon, über die Jahre habe ich ein paar praktikable Methoden für eine bestimmte Ebene der Profilerstellung gefunden. Am einfachsten können Sie natürlich einfach ein FPS-Meter bauen und beobachten, wie es sich verhält. Für mehr Informationen über code-lastige Anwendungen habe ich ein einfaches Framework erstellt, um getTimer() Aufrufe am Anfang und am Ende von Methoden zu erstellen und die kumulative Zeit zu verfolgen, aber ich habe noch nie vorgefertigte Tools dafür verwendet Das. In der Praxis ist es normalerweise ziemlich offensichtlich, wo die Engpässe für Code-schwere Arbeit sind, und in diesen Fällen habe ich Timer direkt um das gelegt, was ich zu optimieren versuche.

Wenn die Engpässe im Rendering sind, ist das erste, was zu versuchen ist, einfach auf Ihrem Ziel FPS zu veröffentlichen, und verwenden Sie ein FPS-Meter zu verfolgen, wenn die tatsächliche Wiedergabe darunter fällt (auf der Zielhardware). Sie können detailliertere Informationen zum Rendern erhalten, indem Sie beispielsweise ein Zeitlimit von 1 ms aufrufen, das refreshAfterUpdate aufruft, und die tatsächliche Zeit zwischen den Aktualisierungen überwachen. Leider können Sie nicht mehr granular als "pro Aktualisierung" erhalten - Sie können nicht direkt sehen, wie viel Zeit für das Rastern, Compositing usw. aufgewendet wird (obwohl Sie diese Dinge oft ableiten können. Beispielsweise können Sie Bitmap-Caching aktivieren auf vektorhohe Objekte, um Rasterung von der Tabelle zu nehmen, und beobachten Sie die Ergebnisse.)

+0

Dieser Link zeigt auf Flex Builder 3 Feature-Einführungen - ist das nicht die aktuelle Version? – hasseg

+0

Whoah, du hast Recht - du kannst sehen, ich bin kein FB-Benutzer. Ich werde zur besseren Übersicht bearbeiten, aber vielleicht kann jemand, der mit dem FB-Profiler vertrauter ist, Infos über das In- und Outs hinzufügen. Danke für den Fang! – fenomas

2

Es ist wichtig zu beachten, dass die Flash Player-Implementierung auf jeder Plattform und zu einem gewissen Grad unterschiedlich ist, erwarten Sie daher erhebliche Geschwindigkeitsunterschiede. Wenn Sie also eine ressourcenintensive Anwendung entwickeln, sollten Sie Profiling-Tools verwenden, die für jedes Betriebssystem spezifisch sind, wie z. B. Instruments unter OS X, und natürlich die Leistung in jedem Browser testen.

2

Ich habe den Profiler verwendet, der mit Flex Builder 3 mit mäßigem Erfolg kommt. Ich finde es besonders nützlich, Speicherlecks und GC-Probleme zu finden.

Es war viel weniger nützlich für mich auf dem Gebiet der Time-in-Methode Leistung aufgrund der asynchronen Natur der Anwendung in Frage und die Zeit für [onEnterFrame] und andere interne Methoden, obwohl ich noch war in der Lage, basierend auf der Ausgabe einige Optimierungen vorzunehmen.

16

Ich war auch auf der Suche nach einem Profiler für AS, aber ich wollte eine Freeware/Open Source-Lösung, die mit FlashDevelop und Flex SDK funktioniert. Ich habe keine gefunden. Also schrieb ich ein einfaches Python-Skript und eine noch einfachere AS-Klasse. Das Skript nimmt im Wesentlichen jede AS-Datei und fügt Profilierungscode (d. H. Aufrufe zum Messen der Gesamtlaufzeit dieser Funktion mit einer Genauigkeit von 1 ms - die Auflösung des Aufrufs flash.utils.getTimer()) zu jeder Funktionsdefinition hinzu. Das Skript macht manchmal Fehler, aber diese sind normalerweise leicht von Hand zu beheben. Dann müssen Sie eine weitere Zeile manuell hinzufügen: Speichern Sie die Profiling-Statistiken irgendwo ab. Diese Methode ist offensichtlich weit entfernt von der Genauigkeit, aber dennoch gibt es ein gutes Gefühl für Engpässe in Ihrem Code. Ich habe es für eine 100k-Datei mit Erfolg verwendet.

Hier ist die Klasse 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; 
     } 
    } 
} 

Und hier ist das Python-Skript, das funktioniert der 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() 

Fühlen Sie sich frei zu verwenden, verteilen und beide zu ändern.

+0

Wow, nette Arbeit! – andrewrk

+0

Ich erhalte einen Fehler in Zeile 31 des Python-Skripts: UnboundLocalError: Lokale Variable 'Klass' referenziert vor Zuweisung –

+0

Ich habe eine Zeile hinzugefügt, um die Klasse am Anfang der Funktion zu initialisieren. –

2

Ich schrieb einen Flash-Profiler auf der Grundlage von FLASM vor einer Weile (http://snow.prohosting.com/bensch/flasp.html) Sie müssen FLASM verwenden, um die Profilierungs-Asm einzufügen und dann das Programm ausführen.

Ein anderer (vielleicht) besserer Weg ist es, David Changs Profiling-Code zu verwenden, der überhaupt keine Flams erfordert. www.nochump.com/asprof/

prost

2

Dies ist mein persönlicher Favorit. Beachten Sie, dass es auf Java und Open Source basiert. http://github.com/bengarney/PBLabsProfiler

Es verwendet undokumentierte Funktionen des Flash/Flex-Compilers. Die gleichen Flash Builder eingebauten Profiler verwendet. Und ja! Ich habe es erfolgreich verwendet, um einige meiner Flash-Code zu optimieren.

+1

Ja, PushButton Labs Profiler machen den Job sehr gut! –

0

Es gibt eine FlashPreloaderProfiler: http://jpauclair.net/flashpreloadprofiler

Es ist in Actionscript geschrieben ist, braucht nicht eine Java-Anwendung im Hintergrund ausgeführt wird und einige weitere Features wie Memory Profiler haben.

Aber ich ziehe PBLabsProfiler auch :)

1

ich The Miner gefunden haben sehr nützlich zu sein, und es ist kostenlos für nicht-kommerzielle Projekte. Es hat eine breite Palette von Funktionen, aber die Registerkarte "Performance Profiler" war am hilfreichsten. Ich finde, dass es eine gute Möglichkeit ist, Engpässe in Ihrem Code zu finden, oder zumindest wissen, was die Hauptursache ist (Rendering, Text, Netzwerk, etc ..).

Ich brauchte ein wenig, um die Installationsanweisungen zu finden, aber es ist ziemlich einfach. Schließen Sie die SWC-Datei in Ihr Projekt ein und fügen Sie dann eine Zeile Code in Ihren Dokumentklassenkonstruktor ein.

this.addChild(new TheMiner(true)); 

Weiteren Informationen: http://www.sociodox.com/theminer/support.html

6

Adobe hat vor kurzem ein neues Profilierungswerkzeuges für Flash namens Adobe Scout-Freigabe:

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

Es ist eine massive Verbesserung auf dem alten Profiler Flash Builder - es gibt Ihnen eine detaillierte Aufschlüsselung der CPU-Zeit, sowohl für ActionScript-Ausführung als auch für interne Player-Funktionen wie Rendering und Netzwerk.

Es ist kostenlos für eine Probezeit - Sie müssen nur für ein kostenloses Creative Cloud-Konto registrieren. Danach wird es weiterhin eine kostenlose Basisversion geben, wobei die Vollversion als Teil eines bezahlten Creative Cloud-Kontos verfügbar sein wird.