Flash / Actionscript CPU профилировщик

Вы нашли такой инструмент и успешно его использовали?

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 - оно дает подробную разбивку процессорного времени, как для выполнения ActionScript, так и для внутренних функций проигрывателя, таких как рендеринг и работа в сети.

Это бесплатно на пробный период - вам просто нужно зарегистрироваться для бесплатной учетной записи Creative Cloud. После этого будет оставаться бесплатная базовая версия, полная версия будет доступна как часть платной учетной записи Creative Cloud.

Важно отметить, что реализация Flash Player различна для каждой платформы и в некоторой степени для каждого браузера, поэтому ожидайте заметных различий в скорости. Поэтому, если вы разрабатываете ресурсоемкое приложение, вам следует использовать инструменты профилирования, специфичные для каждой ОС, на которую вы ориентируетесь, например, инструменты на OS X и, конечно, тестировать производительность в каждом браузере.

Этот мой любимый. Обратите внимание, что он построен на Java и с открытым исходным кодом. http://github.com/bengarney/PBLabsProfiler

Он использует недокументированные возможности компилятора flash/flex. Те же, что использует встроенный профилировщик Flash Builder. И да! Я успешно использовал его, чтобы оптимизировать мой флеш-код.

Некоторое время назад я написал флеш-профилировщик на основе Flash ( http://snow.prohosting.com/bensch/flasp.html). Вам нужно использовать FlashM, чтобы вставить профилирующий asm, а затем запустить программу.

Другой (может быть) лучший способ - использовать код профилирования Дэвида Чанга, который вообще не требует flashm. www.nochump.com/asprof/

ура

Я использовал профилировщик, который поставляется с Flex Builder 3, с умеренным успехом. Я нахожу особенно полезным при поиске утечек памяти и / или проблем с ГХ.

Это было намного менее полезно для меня в области производительности времени в методе из-за асинхронного характера рассматриваемого приложения и количества времени, отведенного для [onEnterFrame] и других внутренних методов, хотя я все еще был в состоянии сделать некоторые оптимизация на основе результатов.

Flex Builder 3 содержит профилировщик производительности и памяти. Я не использовал это, но это выглядит довольно шикарно. Я не уверен, что его можно использовать для контента не-Flex, но он определенно будет работать только для AS3.

Кроме того, на протяжении многих лет я нашел несколько работоспособных методов для определенного уровня профилирования. Самое простое, очевидно, можно просто построить счетчик FPS и посмотреть, как он себя ведет. Для получения дополнительной информации о приложениях с большим количеством кода я сделал одну простую платформу для создания getTimer() вызывает в начале и в конце методов и отслеживает совокупное время, но я никогда не использовал для этого никаких готовых инструментов. На практике обычно довольно очевидно, где узкие места предназначены для работы с большим количеством кода, и в этих случаях я просто помещаю таймер непосредственно вокруг того, что я пытаюсь оптимизировать.

Когда узкие места возникают при рендеринге, первое, что нужно попробовать, это просто опубликовать на целевом FPS и использовать индикатор FPS, чтобы отслеживать, когда фактическое воспроизведение падает ниже этого (на целевом оборудовании). Вы можете получить более подробную информацию о рендеринге, например, вызвав тайм-аут на 1 мс, который вызывает refreshAfterUpdateи отслеживание фактического времени между обновлениями. К сожалению, вы не можете получить более детальную информацию, чем "за обновление" - вы не можете непосредственно увидеть, сколько времени потрачено на растеризацию, компоновку и т. Д. (Хотя вы можете часто делать выводы об этом. Например, вы можете включить растровое кэширование на объектах с векторным весом убрать растеризацию со стола и наблюдать за результатами.)

Я считаю, что The Miner очень полезен и бесплатен для некоммерческих проектов. Он имеет широкий спектр функций, но вкладка с надписью "Performance Profiler" была наиболее полезной. Я считаю, что это отличный способ найти узкие места в вашем коде или, по крайней мере, узнать, что является основной причиной (рендеринг, текст, сеть и т. Д.).

Мне потребовалось немного времени, чтобы найти инструкции по установке, но все довольно просто. Включите файл.swc в свой проект, затем добавьте 1 строку кода в конструктор класса документа.

this.addChild(new TheMiner(true));

Дополнительная информация: http://www.sociodox.com/theminer/support.html

Есть FlashPreloaderProfiler: http://jpauclair.net/flashpreloadprofiler

Он написан на ActionScript, не требует java-приложения, работающего в фоновом режиме, и имеет некоторые дополнительные функции, такие как Memory Profiler.

Но я предпочитаю PBLabsProfiler тоже:)

Другие вопросы по тегам