История Traceview.
Недавно я сделал серьезный взгляд на Traceview, и мне пришло в
голову,во-первых, что есть, вероятно, несколько других разработчиков
Android,которые не использовали его,и во-вторых,это возможность читать
лекции на одной из моих любимых тем: повышение производительности и
профилирования.Это,пожалуй,немного Android-101; если вы уже знаете
все о Traceview,вы можете остановиться здесь и вернуться к кодированию.
Создание службы быстрого запуска.
Для любого приложения, которое даже средней сложности, вы не достаточно
умны,чтобы предсказать,какие части будут медленно работать,потому что
никто не достаточно умен, чтобы предсказать, где программное обеспечение
имеет узкие места.
Написать быстро приложение и построить его простым способом,которые
могли бы работать,избегая глупых вещей,как алгоритмы порядка -
N-квадратов и делать ввод / вывод в потоке пользовательского интерфейса
Android. Кто знает, может быть достаточно быстро, а затем увы!
Если это не достаточно быстро, догадаться сразу почему сложно.
Но узнать это можно используя Profiler.На самом деле я сделал это,
когда был загнан в угол, используя такие вещи,как System.err.println.
К счастью,Android поставляется с довольно приличным Profiler,так что
вы не должны получить уродливые приложения.
Case Study: спасатель 2
У меня эта маленькая утилита в Android Market называется она спаситель 2.
С одной стороны,она читает SMS и телефонные вызовы выходят из системы
и сохраняются в текстовый файл JSON на карту SD.Этот процесс идёт довольно
медленно, это показывает хороший динамический индикатор.Я задался вопросом,
почему этот процесс идёт так медленно,чтобы записать несколько сотен записей
в текстовый файл на устройство,которое,в конце концов,имеет гигагерцовый
процессор.
Тот, кто предполагает,что замедление идёт из-за машин ContentProvider
чтения системных журналов,или если это невозможно,расходы на запись
в карту SD. Давайте всё таки узнаем,из-за чего этот процесс идёт так
медленно.
Включение трассировки
В Saver.java поставьте скобки в коде в свой код- метод выглядит вот так:
public void run() { android.os.Debug.startMethodTracing("lsd"); // ... method body elided android.os.Debug.stopMethodTracing(); }
Первый вызов сделает трассировку, аргумент"
lsd
"
(stands for Life Saver Debug, of course)скажет системе куда положить код - / SDCard / lsd.trace. Помните, что делая это,вы должны добавить WRITE_EXTERNAL_STORAGE разрешения,чтобы вы можли сохранить информацию ;не забудьте затем удалить,прежде чем закончите. Инженер Android Xavier Ducrohet пишет,чтобы напомнить:"DDMS имеет кнопку запуска и остановки профилирования " Device View.После нажатия на кнопку остановить,запускается файл трассировки TraceView.Это не малозначно, как положить начало/stopMethodTracing в коде,но может быть весьма полезным. Для виртуальных машин раньше,чем Froyo,требуется разрешение,а также (в основном DDMS автоматизировать получение следа от SD-карты и сохранить его локально перед вызовом traceview).Для Froyo ВМ-ВМ может отправить файл трассировки через соединение JDWP и разрешения не нужны (что действительно полезно). " Когда вы запустите приложение,то вы скопируете на ваш компьютер и запустите Traceview. 540> adb pull /sdcard/lsd.trace 541> traceview lsd
На данный момент, вы должны были заметить три вещи. Во-первых, превращение отслеживания на самом деле замедляет работу приложения. Во-вторых, tracefile большой, в этом случае нужны 8.6m для запуска, которые имели, как четыре секунды. В-третьих, что traceview выглядит довольно прохладно.
Бар в верхней панели показывает приложение и темы и как они розделены по времени, так как Nexus однопоточный процессор,и они выполняются по очереди. Сделайте нуль на одном 100-мс сегменте.
В верхней строке, где выполняется код приложения (красный сегмент GC ), в средней линии в потоке пользовательского интерфейса и всплески активности ProgressBar обновления, не знаю, что за третий поток, названный HeapWorker, но это не представляется одной из основных причин выполнения приложения,давайте его игнорировать.
В нижней части экрана, где действительно интересные данные, он показывает, какой из ваших методов потратил время, и может быть отсортирован кучей разных способов. Давайте сосредоточимся на первых двух линиях.
Перевод на английский язык, это говорит о том, что на высшем уровне рутинных работ потребляется 100% от времени, если вы включите все,но только 0,9% само время. Следующая строка вдруг начинает получать реальное интересно: java.io.PrintStream.println (Object) и все, что он вызывает используют 65,2% времени приложения. Это код, который пишет JSON на карту SD. Сейчас, мы знаем, что по-видимому задача вытягивать данные из ContentProviders телефона, кажется, не очень дорогой.
Можем ли мы заключить, что приложение ограничивается плохим написанием производительность карты SD? Давайте детализируем, что и как делается в наиболее очевидных точках.
Есть неприятный сюрприз. Конечно, println звонки (по сути) ToString для всех своих аргументов. Похоже, что превращение аргументов в строки занимает более половины времени, прежде чем он напишет println (объекты) на println (String).
Рассмотрим пошагово детализацию в println (String), это позволит предположить, что есть некоторые медленные I / O и происходят они на карте SD. Но давайте посмотрим, что внутри String.valueOf вызова.
Оказывается, что org.json.JSONObject.toString является тем, что профессиональные программисты называют семейными операциями, поэтому мы туда не пойдём.Вы можете копаться в нем, но это просто удручает.
Что же можно сделать — отсортировать все процедуры по их «Эксклюзив» , как и число процессоров. Здесь все из них, которые используют 1% или более от общего времени выполнения.
Там в немного GC и Android рамках просмотр споры вещи там, но дисплей доминируют org.jason и java.lang.StringBuilder кода.
Заключение
Реальный вывод, что в случае этого приложения можно действительно не заботятся о производительности. Пользователь запускает его из общей суммы два раза, один раз на старый телефон и один раз на новый телефон, так что я не думаю, что в этом есть проблемы.
Чтобы ускорить этот процесс нужно сделать — во-первых, либо отказаться от использования JSON, или найти более дешевый способ сериализации . Во-вторых, сделать меньше println вызовов, хранить данные вместе в одном большом буфере и просто ускорить его с первого ввода / вывода вызова. Traceview это хороший инструмент, и если вы еще не знаете его, вы обязаны сделать это ради себя, чтобы научиться этому.