2008-12-10 7 views

Respuesta

1

Flex Builder 3 incluye un performance and memory profiler. No lo he usado, pero se ve bastante elegante. No estoy seguro si se puede usar para contenido que no sea de Flex, pero definitivamente solo funcionará para AS3.

Aparte de eso, a lo largo de los años he encontrado un par de métodos viables para un cierto nivel de creación de perfiles. De la forma más simple, obviamente puedes simplemente construir un medidor de FPS y observar cómo se comporta. Para obtener más información sobre las aplicaciones con muchos códigos, una cosa que he hecho es crear un marco simple para hacer llamadas al getTimer() al principio y al final de los métodos y seguir el tiempo acumulado, pero nunca he usado herramientas prefabricadas para ese. En la práctica, suele ser bastante obvio dónde están los cuellos de botella para el trabajo pesado de código, y en esos casos pongo el temporizador directamente alrededor de lo que estoy tratando de optimizar.

Cuando los cuellos de botella se procesan, lo primero que debe hacer es simplemente publicar en su FPS objetivo y usar un medidor FPS para rastrear cuando la reproducción real caiga por debajo (en el hardware de destino). Puede obtener información más detallada acerca de la representación, por ejemplo, invocando un tiempo de espera de 1ms que llama al refreshAfterUpdate, y supervisa el tiempo real entre las actualizaciones. Desafortunadamente, no se puede obtener más granular que "por actualización": no se puede ver directamente cuánto tiempo se pasa rastrillando, componiendo, etc. (aunque a menudo puede inferir estas cosas. Por ejemplo, puede habilitar el almacenamiento en caché de mapas de bits). en objetos vectoriales pesados ​​para quitar la rasterización de la tabla y observar los resultados)

+0

Ese enlace apunta a las presentaciones de características de Flex Builder 3: ¿no es esa la versión actual? – hasseg

+0

Whoah, tienes razón, puedes ver que no soy un usuario de FB. Voy a editar para mayor claridad, pero tal vez alguien más familiarizado con el generador de perfiles FB puede agregar información sobre los pormenores. Gracias por la captura! – fenomas

2

Es importante tener en cuenta que la implementación de Flash Player es diferente en cada plataforma y en cada navegador, por lo que se esperan diferencias de velocidad notables. Por lo tanto, si está desarrollando una aplicación de uso intensivo de recursos, debe utilizar herramientas de creación de perfiles específicas para cada sistema operativo al que se dirige, como por ejemplo Instruments en OS X y, por supuesto, probar el rendimiento en cada navegador.

2

He utilizado el generador de perfiles que viene con Flex Builder 3 con un éxito moderado. Me resulta especialmente útil para encontrar fugas de memoria y/o problemas de GC.

Me resultó mucho menos útil en el área del rendimiento del tiempo en el método debido a la naturaleza asíncrona de la aplicación en cuestión y la cantidad de tiempo otorgada a [onEnterFrame] y otros métodos internos, aunque todavía estaba capaz de hacer algunas optimizaciones basadas en la salida.

16

También estaba buscando un generador de perfiles para AS, pero quería una solución freeware/de código abierto que funcionara con FlashDevelop y Flex SDK. No encontré ninguno. Así que escribí un script de python simple y una clase AS aún más simple. La secuencia de comandos toma esencialmente cualquier archivo AS y agrega un código de generación de perfiles (es decir, llamadas para medir el tiempo de ejecución total de esa función con una precisión de 1 ms - la resolución de la llamada flash.utils.getTimer()) a cada definición de función. La secuencia de comandos a veces comete errores, pero estos son generalmente fáciles de corregir a mano. Luego necesita agregar una línea más manualmente: volcar las estadísticas de creación de perfiles en algún lugar en algún momento. Este método obviamente no es preciso, pero no obstante le da una buena idea de los cuellos de botella en su código. Lo utilicé para un archivo de 100k con éxito.

Aquí está la clase 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; 
     } 
    } 
} 

Y aquí es el script en Python que hace el truco:

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() 

no dude en utilizar, distribuir y modificar ambos.

+0

Guau, buen trabajo! – andrewrk

+0

Recibo un error en la línea 31 del script de python: UnboundLocalError: variable local 'klass' referenciada antes de la asignación –

+0

Agregué una línea para inicializar klass al inicio de la función. –

2

Escribí un generador de perfiles flash basado en flasm hace un tiempo (http://snow.prohosting.com/bensch/flasp.html) Debe utilizar flasm para insertar el perfil asm y luego ejecutar el programa.

Otra (tal vez) mejor manera es utilizar el código de perfil de David Chang que no requiere flasm en absoluto. www.nochump.com/asprof/

aplausos

2

Ésta es mi favorito personal. Tenga en cuenta que está basado en Java y en código abierto. http://github.com/bengarney/PBLabsProfiler

Utiliza las características no documentadas del compilador de flash/flex. Los mismos que utiliza Profiler incorporado de Flash Builder. ¡Y sí! Lo he usado con éxito para optimizar algunos de mis códigos flash.

+1

Sí, PushButton Labs Profiler hace el trabajo muy bien! –

0

Hay una FlashPreloaderProfiler: http://jpauclair.net/flashpreloadprofiler

Está escrito en ActionScript, no necesita un Java-aplicación ejecutándose en segundo plano y tiene algunas características más, como la memoria de perfiles.

pero prefiero PBLabsProfiler también :)

1

he encontrado The Miner a ser muy útil, y es gratis para los proyectos no comerciales. Tiene una amplia gama de características, pero la pestaña etiquetada como "Performance Profiler" ha sido de lo más útil. Encuentro que es una gran manera de encontrar cuellos de botella en su código, o al menos saber cuál es la causa principal (Representación, Texto, Red, etc.).

Me llevó un poco encontrar las instrucciones de instalación, pero es bastante simple. Incluya el archivo .swc en su proyecto, luego agregue 1 línea de código en su constructor de clase de documento.

this.addChild(new TheMiner(true)); 

Más información: http://www.sociodox.com/theminer/support.html

6

Adobe ha lanzado recientemente una nueva herramienta de perfilado para Flash llamado Adobe Scout:

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

Es una enorme mejora en el viejo perfilador Flash Builder - se proporciona un desglose detallado del tiempo de la CPU, tanto para la ejecución de ActionScript como para las funciones internas del reproductor, como el procesamiento y la creación de redes.

Es gratis durante un período de prueba; solo necesita registrarse para obtener una cuenta Creative Cloud gratuita. Después de eso, seguirá habiendo una versión básica gratuita, con la versión completa disponible como parte de una cuenta de Creative Cloud pagada.