مطالعه موردی: چگونه تیم Gmail Wear OS راه اندازی برنامه خود را تا 50% بهبود بخشید، مطالعه موردی: چگونه تیم Gmail Wear OS راه اندازی برنامه خود را 50% بهبود داد، مطالعه موردی: چگونه تیم Gmail Wear OS راه اندازی برنامه خود را 50% بهبود بخشید. ,مطالعه موردی: چگونه تیم Gmail Wear OS راه اندازی اپلیکیشن خود را تا 50 درصد بهبود بخشید

راه اندازی برنامه نشان دهنده اولین تاثیر برنامه شما بر روی کاربران است. و کاربران دوست ندارند منتظر بمانند، بنابراین باید مطمئن شوید که برنامه شما سریع شروع می شود. برای اینکه به شما نشان دهیم چگونه یک تیم توسعه برنامه واقعی مشکلات مربوط به راه‌اندازی برنامه خود را پیدا کرده و آنها را تشخیص داده‌اند، تیم Gmail Wear OS چه کاری انجام داد.

تیم Gmail Wear OS یک تلاش بهینه‌سازی را با تمرکز ویژه بر راه‌اندازی برنامه و عملکرد رندر زمان اجرا انجام داد تا معیارهای عملکرد برنامه تیم خود را برآورده کند. با این حال، حتی اگر آستانه خاصی برای هدف گذاری نداشته باشید، اگر کمی برای بررسی آن صرف کنید، تقریباً همیشه فضایی برای بهبود راه اندازی برنامه وجود دارد.

یک ردیابی بگیرید و به راه اندازی برنامه نگاه کنید

برای شروع تجزیه و تحلیل، ردی را ثبت کنید که شامل راه اندازی برنامه برای بررسی دقیق تر در Perfetto یا Android Studio است. این مطالعه موردی از Perfetto استفاده می‌کند زیرا به شما نشان می‌دهد که در سراسر سیستم دستگاه، فراتر از برنامه شما، چه اتفاقی می‌افتد. وقتی ردیابی را در Perfetto آپلود می کنید، به نظر می رسد:

شکل 1. نمای اولیه ردیابی در Perfetto.

از آنجایی که تمرکز بر بهبود راه‌اندازی برنامه است، ردیف را با معیار سفارشی Startups برنامه Android تعیین کنید. پین کردن آن به بالای نمای خود با کلیک کردن روی نماد پین مفید است هنگامی که ماوس را روی ردیف نگه می دارید ظاهر می شود. نوار یا تکه‌ای که در ردیف راه‌اندازی برنامه Android مشاهده می‌کنید، محدوده زمانی را نشان می‌دهد که راه‌اندازی برنامه پوشش می‌دهد، تا زمانی که اولین فریم برنامه روی صفحه کشیده شود، بنابراین باید در آنجا به دنبال مشکلات یا تنگناها بگردید.

ردیف راه‌اندازی برنامه Android با گزینه پین ​​کردن برجسته شده است.
شکل 2. برای تجزیه و تحلیل آسان‌تر، معیار سفارشی Startups برنامه Android را به بالای داشبورد خود پین کنید.

توجه داشته باشید که معیار شروع برنامه اندروید، زمان نمایش اولیه را نشان می‌دهد، حتی اگر از reportFullyDrawn() استفاده می‌کنید. برای شناسایی زمان نمایش کامل ، reportFullyDrawn() را در کادر جستجوی Perfetto جستجو کنید.

موضوع اصلی را بررسی کنید

ابتدا بررسی کنید ببینید در موضوع اصلی چه اتفاقی می افتد. موضوع اصلی بسیار مهم است زیرا معمولاً در آنجاست که تمام رندرهای رابط کاربری در آنجا اتفاق می‌افتد. وقتی مسدود می شود، هیچ ترسیمی نمی تواند اتفاق بیفتد و به نظر می رسد برنامه شما ثابت است. بنابراین می‌خواهید مطمئن شوید که هیچ عملیات طولانی‌مدت در حال اجرا در رشته اصلی انجام نمی‌شود.

برای پیدا کردن رشته اصلی، ردیف را با نام بسته برنامه خود پیدا کنید و آن را گسترش دهید. دو ردیف با همان نام بسته (معمولاً دو ردیف اول در بخش) نشان دهنده موضوع اصلی است. از دو ردیف رشته اصلی، اولین نشان دهنده وضعیت CPU و ردیف دوم نشان دهنده نقاط ردیابی است. دو ردیف رشته اصلی را در زیر متریک راه‌اندازی برنامه Android پین کنید.

راه‌اندازی‌های برنامه Android و ردیف‌های رشته اصلی پین شدند.
شکل 3. ردیف های رشته اصلی را در زیر متریک سفارشی راه اندازی برنامه Android برای کمک به تجزیه و تحلیل پین کنید.

زمان صرف شده در وضعیت قابل اجرا و اختلاف CPU

برای دریافت نمای کلی از فعالیت CPU در هنگام راه‌اندازی برنامه، مکان‌نمای خود را روی رشته اصلی بکشید تا محدوده زمانی راه‌اندازی برنامه را ثبت کنید. پانل Thread States که ظاهر می شود، کل زمان صرف شده در هر وضعیت CPU را در محدوده زمانی انتخابی شما نشان می دهد.

به زمان صرف شده در حالت Runnable نگاه کنید. هنگامی که یک رشته در حالت Runnable است، رشته برای انجام کار در دسترس است اما هیچ کاری برنامه ریزی نشده است. این می تواند نشان دهد که دستگاه تحت بار سنگین است و قادر به برنامه ریزی وظایف با اولویت بالا نیست. برنامه برتر و قابل مشاهده برای کاربر، بالاترین اولویت را در زمان‌بندی دارد، بنابراین یک رشته اصلی بی‌کار اغلب نشان می‌دهد که فرآیندهای فشرده در برنامه شما، مانند رندر کردن انیمیشن، با رشته اصلی برای زمان CPU رقابت می‌کنند.

موضوع اصلی با زمان کل در حالت های مختلف در پانل وضعیت های موضوع برجسته شده است.
شکل 4. زمان نسبی را در حالت های Runnable to Running ارزیابی کنید تا متوجه شوید که چقدر اختلاف CPU وجود دارد.

هر چه نسبت زمان در حالت Runnable به زمان در Running بیشتر باشد، احتمال بروز اختلاف در CPU بیشتر است. هنگام بررسی مشکلات عملکرد به این روش، ابتدا روی طولانی ترین فریم در حال اجرا تمرکز کنید و به سمت موارد کوچکتر کار کنید.

هنگام تجزیه و تحلیل زمان صرف شده در حالت Runnable ، سخت افزار دستگاه را در نظر بگیرید. از آنجایی که برنامه نشان داده شده روی یک دستگاه پوشیدنی با دو CPU اجرا می شود، انتظار می رود زمان بیشتری در حالت Runnable صرف شود و اختلاف CPU بیشتر با سایر فرآیندها نسبت به زمانی که به دستگاهی با CPU بیشتر نگاه کنیم. حتی اگر زمان بیشتری در حالت Runnable بیش از حد انتظار برای یک برنامه تلفن معمولی صرف می شود، ممکن است در زمینه پوشیدنی ها قابل درک باشد.

زمان صرف شده در OpenDexFilesFromOat*

اکنون زمان صرف شده در OpenDexFilesFromOat* را بررسی کنید. در trace، همزمان با برش bindApplication اتفاق می افتد. این برش نشان دهنده زمان صرف شده برای خواندن فایل های DEX برنامه است.

معاملات بایندر مسدود شده است

سپس تراکنش‌های بایندر را بررسی کنید. تراکنش‌های Binder نشان‌دهنده تماس‌های بین کلاینت و سرور است: در این حالت، برنامه (سرویس‌گیر) سیستم اندروید (سرور) را با یک binder transaction فراخوانی می‌کند و سرور با یک binder reply پاسخ می‌دهد. اطمینان حاصل کنید که برنامه در هنگام راه‌اندازی، تراکنش‌های بایندر غیرضروری انجام نمی‌دهد، زیرا خطر اختلاف CPU را افزایش می‌دهند. اگر می‌توانید، کارهایی که شامل تماس‌های بایندر است را به بعد از دوره راه‌اندازی برنامه موکول کنید. اگر باید تراکنش‌های بایندر انجام دهید، مطمئن شوید که بیشتر از نرخ تازه‌سازی Vsync دستگاه شما طول نمی‌کشد.

اولین تراکنش بایندر که معمولاً همزمان با برش ActivityThreadMain انجام می شود، در این مورد بسیار طولانی به نظر می رسد. برای کسب اطلاعات بیشتر در مورد آنچه ممکن است اتفاق بیفتد، این مراحل را دنبال کنید:

  1. برای مشاهده پاسخ مربوط به کلاسور و کسب اطلاعات بیشتر درباره نحوه اولویت بندی تراکنش بایندر، بر روی بخش مورد علاقه تراکنش کلاسور کلیک کنید.
  2. برای مشاهده پاسخ کلاسور، به پنل Current Selection رفته و در قسمت Following threads، روی پاسخ binder کلیک کنید. فیلد Thread همچنین رشته‌ای را به شما می‌گوید که اگر بخواهید به صورت دستی به آنجا بروید، پاسخ binder در آن رخ می‌دهد. در یک روند متفاوت خواهد بود. خطی ظاهر می شود که تراکنش بایندر و پاسخ را به هم متصل می کند.

    یک خط تماس و پاسخ بایندر را متصل می کند.
    شکل 5. تراکنش‌های بایندر را که در حین راه‌اندازی برنامه اتفاق می‌افتند، شناسایی کنید و ارزیابی کنید که آیا می‌توانید آنها را به تعویق بیندازید.
  3. برای اینکه ببینید سرور سیستم چگونه این تراکنش بایندر را مدیریت می کند، رشته های Cpu 0 و Cpu 1 را به بالای صفحه خود پین کنید.

  4. با یافتن برش هایی که شامل نام رشته پاسخ کلاسور هستند، در این مورد "Binder:687_11 [2542]"، فرآیندهای سیستمی را که پاسخ binder را مدیریت می کنند، بیابید. برای دریافت اطلاعات بیشتر در مورد تراکنش بایندر، روی فرآیندهای سیستم مربوطه کلیک کنید.

به این فرآیند سیستمی مرتبط با تراکنش بایندر مورد علاقه که در CPU 0 رخ می دهد، نگاهی بیندازید:

فرآیند سیستم با حالت پایانی «قابل اجرا» (پیش‌گیری).
شکل 6. فرآیند سیستم در حالت Runnable (Preempted) قرار دارد که نشان می دهد با تاخیر مواجه می شود.

حالت پایانی می‌گوید Runnable (Preempted) به این معنی است که فرآیند به تعویق می‌افتد زیرا CPU کار دیگری انجام می‌دهد. برای اینکه بفهمید چه چیزی از آن پیشی گرفته است، ردیف های Ftrace Events را گسترش دهید. در برگه Ftrace Events که در دسترس می‌شود، پیمایش کنید و رویدادهای مربوط به رشته کلاسور مورد علاقه "Binder:687_11 [2542]" را جستجو کنید. در حول و حوش زمانی که فرآیند سیستم از قبل اجرا می‌شود، دو رویداد سرور سیستم که شامل آرگومان "decon" می‌شود، رخ داده است، که به این معنی است که آنها به کنترل‌کننده نمایشگر مرتبط هستند. این منطقی به نظر می رسد زیرا کنترل کننده صفحه نمایش فریم ها را روی صفحه قرار می دهد - یک کار مهم! پس رویدادها را همانطور که هست رها کنید.

رویدادهای FTrace مرتبط با معامله بایندر مورد علاقه برجسته شده است.
شکل 7. رویدادهای FTrace نشان می‌دهد که تراکنش بایندر توسط رویدادهای کنترل‌کننده نمایش به تأخیر می‌افتد.

فعالیت JIT

برای بررسی فعالیت جمع‌آوری به‌موقع (JIT) ، فرآیندهای متعلق به برنامه‌تان را گسترش دهید، دو ردیف «Jit Thread Pool» را پیدا کنید و آن‌ها را به بالای نمای خود پین کنید. از آنجایی که این برنامه از نمایه‌های خط پایه در هنگام راه‌اندازی برنامه بهره می‌برد، فعالیت JIT بسیار کمی تا زمانی که اولین فریم ترسیم شود، رخ می‌دهد که با پایان اولین تماس Choreographer.doFrame مشخص می‌شود. با این حال، به دلیل شروع آهسته JIT compiling void توجه کنید، که نشان می دهد فعالیت سیستمی که در طول نقطه ردیابی با برچسب Application creation اتفاق می افتد، باعث ایجاد فعالیت های پس زمینه JIT زیادی می شود. برای حل این مشکل، رویدادهایی را که مدت کوتاهی پس از ترسیم اولین فریم اتفاق می‌افتند، با گسترش مجموعه نمایه به نقطه‌ای که برنامه آماده استفاده است، به نمایه خط پایه اضافه کنید. در بسیاری از موارد، می‌توانید این کار را با افزودن یک خط به انتهای تست ماکرو بنچمارک مجموعه پروفایل پایه خود انجام دهید که منتظر می‌ماند تا ویجت UI خاصی روی صفحه نمایش شما ظاهر شود و نشان می‌دهد که صفحه کاملاً پر شده است.

مخزن رشته‌های Jit با برش «Jit compiling void» برجسته شده است.
شکل 8. اگر فعالیت های JIT زیادی مشاهده کردید، نمایه خط پایه خود را تا جایی گسترش دهید که برنامه آماده استفاده باشد.

نتایج

در نتیجه این تجزیه و تحلیل، تیم Gmail Wear OS پیشرفت های زیر را انجام داد:

  • از آنجایی که در هنگام راه‌اندازی برنامه هنگام مشاهده فعالیت CPU متوجه مشاجره شدند، انیمیشن اسپینر مورد استفاده برای نشان دادن بارگیری برنامه را با یک تصویر ثابت جایگزین کردند. آنها همچنین برای به تعویق انداختن حالت درخشش، دومین حالت صفحه نمایش که برای نشان دادن بارگیری برنامه استفاده می شود، اسپلش صفحه را طولانی کردند تا منابع CPU را آزاد کنند. این تاخیر راه اندازی اپلیکیشن را تا 50 درصد بهبود بخشید.
  • از نگاهی به زمان صرف شده در فعالیت OpenDexFilesFromOat* و JIT، آنها بازنویسی R8 پروفایل های پایه را فعال کردند. این تأخیر راه اندازی برنامه را 20٪ بهبود بخشید.

در اینجا چند نکته از تیم در مورد چگونگی تجزیه و تحلیل کارآمد عملکرد برنامه وجود دارد:

  • یک فرآیند در حال انجام را تنظیم کنید که قادر به جمع آوری خودکار آثار و نتایج باشد. راه اندازی ردیابی خودکار برای برنامه خود را با استفاده از معیارسنجی در نظر بگیرید.
  • از تست A/B برای تغییراتی که فکر می‌کنید شرایط را بهبود می‌بخشد، استفاده کنید و اگر این کار را نکردند، آن‌ها را رد کنید. با استفاده از کتابخانه Macrobenchmark می توانید عملکرد را در سناریوهای مختلف اندازه گیری کنید.

برای کسب اطلاعات بیشتر به منابع زیر مراجعه کنید:

،

راه اندازی برنامه نشان دهنده اولین تاثیر برنامه شما بر روی کاربران است. و کاربران دوست ندارند منتظر بمانند، بنابراین باید مطمئن شوید که برنامه شما سریع شروع می شود. برای اینکه به شما نشان دهیم چگونه یک تیم توسعه برنامه واقعی مشکلات مربوط به راه‌اندازی برنامه خود را پیدا کرده و آنها را تشخیص داده‌اند، تیم Gmail Wear OS چه کاری انجام داد.

تیم Gmail Wear OS یک تلاش بهینه‌سازی را با تمرکز ویژه بر راه‌اندازی برنامه و عملکرد رندر زمان اجرا انجام داد تا معیارهای عملکرد برنامه تیم خود را برآورده کند. با این حال، حتی اگر آستانه خاصی برای هدف گذاری نداشته باشید، اگر کمی برای بررسی آن صرف کنید، تقریباً همیشه فضایی برای بهبود راه اندازی برنامه وجود دارد.

یک ردیابی بگیرید و به راه اندازی برنامه نگاه کنید

برای شروع تجزیه و تحلیل، ردی را ثبت کنید که شامل راه اندازی برنامه برای بررسی دقیق تر در Perfetto یا Android Studio است. این مطالعه موردی از Perfetto استفاده می‌کند زیرا به شما نشان می‌دهد که در سراسر سیستم دستگاه، فراتر از برنامه شما، چه اتفاقی می‌افتد. وقتی ردیابی را در Perfetto آپلود می کنید، به نظر می رسد:

شکل 1. نمای اولیه ردیابی در Perfetto.

از آنجایی که تمرکز بر بهبود راه‌اندازی برنامه است، ردیف را با معیار سفارشی Startups برنامه Android تعیین کنید. پین کردن آن به بالای نمای خود با کلیک کردن روی نماد پین مفید است هنگامی که ماوس را روی ردیف نگه می دارید ظاهر می شود. نوار یا تکه‌ای که در ردیف راه‌اندازی برنامه Android مشاهده می‌کنید، محدوده زمانی را نشان می‌دهد که راه‌اندازی برنامه پوشش می‌دهد، تا زمانی که اولین فریم برنامه روی صفحه کشیده شود، بنابراین باید در آنجا به دنبال مشکلات یا تنگناها بگردید.

ردیف راه‌اندازی برنامه Android با گزینه پین ​​کردن برجسته شده است.
شکل 2. برای تجزیه و تحلیل آسان‌تر، معیار سفارشی Startups برنامه Android را به بالای داشبورد خود پین کنید.

توجه داشته باشید که معیار شروع برنامه اندروید، زمان نمایش اولیه را نشان می‌دهد، حتی اگر از reportFullyDrawn() استفاده می‌کنید. برای شناسایی زمان نمایش کامل ، reportFullyDrawn() را در کادر جستجوی Perfetto جستجو کنید.

موضوع اصلی را بررسی کنید

ابتدا بررسی کنید ببینید در موضوع اصلی چه اتفاقی می افتد. موضوع اصلی بسیار مهم است زیرا معمولاً در آنجاست که تمام رندرهای رابط کاربری در آنجا اتفاق می‌افتد. وقتی مسدود می شود، هیچ ترسیمی نمی تواند اتفاق بیفتد و به نظر می رسد برنامه شما ثابت است. بنابراین می‌خواهید مطمئن شوید که هیچ عملیات طولانی‌مدت در حال اجرا در رشته اصلی انجام نمی‌شود.

برای پیدا کردن رشته اصلی، ردیف را با نام بسته برنامه خود پیدا کنید و آن را گسترش دهید. دو ردیف با همان نام بسته (معمولاً دو ردیف اول در بخش) نشان دهنده موضوع اصلی است. از دو ردیف رشته اصلی، اولین نشان دهنده وضعیت CPU و ردیف دوم نشان دهنده نقاط ردیابی است. دو ردیف رشته اصلی را در زیر متریک راه‌اندازی برنامه Android پین کنید.

راه‌اندازی‌های برنامه Android و ردیف‌های رشته اصلی پین شدند.
شکل 3. ردیف های رشته اصلی را در زیر متریک سفارشی راه اندازی برنامه Android برای کمک به تجزیه و تحلیل پین کنید.

زمان صرف شده در وضعیت قابل اجرا و اختلاف CPU

برای دریافت نمای کلی از فعالیت CPU در هنگام راه‌اندازی برنامه، مکان‌نمای خود را روی رشته اصلی بکشید تا محدوده زمانی راه‌اندازی برنامه را ثبت کنید. پانل Thread States که ظاهر می شود، کل زمان صرف شده در هر وضعیت CPU را در محدوده زمانی انتخابی شما نشان می دهد.

به زمان صرف شده در حالت Runnable نگاه کنید. هنگامی که یک رشته در حالت Runnable است، رشته برای انجام کار در دسترس است اما هیچ کاری برنامه ریزی نشده است. این می تواند نشان دهد که دستگاه تحت بار سنگین است و قادر به برنامه ریزی وظایف با اولویت بالا نیست. برنامه برتر و قابل مشاهده برای کاربر، بالاترین اولویت را در زمان‌بندی دارد، بنابراین یک رشته اصلی بی‌کار اغلب نشان می‌دهد که فرآیندهای فشرده در برنامه شما، مانند رندر کردن انیمیشن، با رشته اصلی برای زمان CPU رقابت می‌کنند.

موضوع اصلی با زمان کل در حالت های مختلف در پانل وضعیت های موضوع برجسته شده است.
شکل 4. زمان نسبی را در حالت های Runnable to Running ارزیابی کنید تا متوجه شوید که چقدر اختلاف CPU وجود دارد.

هر چه نسبت زمان در حالت Runnable به زمان در Running بیشتر باشد، احتمال بروز اختلاف در CPU بیشتر است. هنگام بررسی مشکلات عملکرد به این روش، ابتدا روی طولانی ترین فریم در حال اجرا تمرکز کنید و به سمت موارد کوچکتر کار کنید.

هنگام تجزیه و تحلیل زمان صرف شده در حالت Runnable ، سخت افزار دستگاه را در نظر بگیرید. از آنجایی که برنامه نشان داده شده روی یک دستگاه پوشیدنی با دو CPU اجرا می شود، انتظار می رود زمان بیشتری در حالت Runnable صرف شود و اختلاف CPU بیشتر با سایر فرآیندها نسبت به زمانی که به دستگاهی با CPU بیشتر نگاه کنیم. حتی اگر زمان بیشتری در حالت Runnable بیش از حد انتظار برای یک برنامه تلفن معمولی صرف می شود، ممکن است در زمینه پوشیدنی ها قابل درک باشد.

زمان صرف شده در OpenDexFilesFromOat*

اکنون زمان صرف شده در OpenDexFilesFromOat* را بررسی کنید. در trace، همزمان با برش bindApplication اتفاق می افتد. این برش نشان دهنده زمان صرف شده برای خواندن فایل های DEX برنامه است.

معاملات بایندر مسدود شده است

سپس تراکنش‌های بایندر را بررسی کنید. تراکنش‌های Binder نشان‌دهنده تماس‌های بین کلاینت و سرور است: در این حالت، برنامه (سرویس‌گیر) سیستم اندروید (سرور) را با یک binder transaction فراخوانی می‌کند و سرور با یک binder reply پاسخ می‌دهد. اطمینان حاصل کنید که برنامه در هنگام راه‌اندازی، تراکنش‌های بایندر غیرضروری انجام نمی‌دهد، زیرا خطر اختلاف CPU را افزایش می‌دهند. اگر می‌توانید، کارهایی که شامل تماس‌های بایندر است را به بعد از دوره راه‌اندازی برنامه موکول کنید. اگر باید تراکنش‌های بایندر انجام دهید، مطمئن شوید که بیشتر از نرخ تازه‌سازی Vsync دستگاه شما طول نمی‌کشد.

اولین تراکنش بایندر که معمولاً همزمان با برش ActivityThreadMain انجام می شود، در این مورد بسیار طولانی به نظر می رسد. برای کسب اطلاعات بیشتر در مورد آنچه ممکن است اتفاق بیفتد، این مراحل را دنبال کنید:

  1. برای مشاهده پاسخ مربوط به کلاسور و کسب اطلاعات بیشتر درباره نحوه اولویت بندی تراکنش بایندر، بر روی بخش مورد علاقه تراکنش کلاسور کلیک کنید.
  2. برای مشاهده پاسخ کلاسور، به پنل Current Selection رفته و در قسمت Following threads، روی پاسخ binder کلیک کنید. فیلد Thread همچنین رشته‌ای را به شما می‌گوید که اگر بخواهید به صورت دستی به آنجا بروید، پاسخ binder در آن رخ می‌دهد. در یک روند متفاوت خواهد بود. خطی ظاهر می شود که تراکنش بایندر و پاسخ را به هم متصل می کند.

    یک خط تماس و پاسخ بایندر را متصل می کند.
    شکل 5. تراکنش‌های بایندر را که در حین راه‌اندازی برنامه اتفاق می‌افتند، شناسایی کنید و ارزیابی کنید که آیا می‌توانید آنها را به تعویق بیندازید.
  3. برای اینکه ببینید سرور سیستم چگونه این تراکنش بایندر را مدیریت می کند، رشته های Cpu 0 و Cpu 1 را به بالای صفحه خود پین کنید.

  4. با یافتن برش هایی که شامل نام رشته پاسخ کلاسور هستند، در این مورد "Binder:687_11 [2542]"، فرآیندهای سیستمی را که پاسخ binder را مدیریت می کنند، بیابید. برای دریافت اطلاعات بیشتر در مورد تراکنش بایندر، روی فرآیندهای سیستم مربوطه کلیک کنید.

به این فرآیند سیستمی مرتبط با تراکنش بایندر مورد علاقه که در CPU 0 رخ می دهد، نگاهی بیندازید:

فرآیند سیستم با حالت پایانی «قابل اجرا» (پیش‌گیری).
شکل 6. فرآیند سیستم در حالت Runnable (Preempted) قرار دارد که نشان می دهد با تاخیر مواجه می شود.

حالت پایانی می‌گوید Runnable (Preempted) به این معنی است که فرآیند به تعویق می‌افتد زیرا CPU کار دیگری انجام می‌دهد. برای اینکه بفهمید چه چیزی از آن پیشی گرفته است، ردیف های Ftrace Events را گسترش دهید. در برگه Ftrace Events که در دسترس می‌شود، پیمایش کنید و رویدادهای مربوط به رشته کلاسور مورد علاقه "Binder:687_11 [2542]" را جستجو کنید. در حول و حوش زمانی که فرآیند سیستم از قبل اجرا می‌شود، دو رویداد سرور سیستم که شامل آرگومان "decon" می‌شود، رخ داده است، که به این معنی است که آنها به کنترل‌کننده نمایشگر مرتبط هستند. این منطقی به نظر می رسد زیرا کنترل کننده صفحه نمایش فریم ها را روی صفحه قرار می دهد - یک کار مهم! پس رویدادها را همانطور که هست رها کنید.

رویدادهای FTrace مرتبط با معامله بایندر مورد علاقه برجسته شده است.
شکل 7. رویدادهای FTrace نشان می‌دهد که تراکنش بایندر توسط رویدادهای کنترل‌کننده نمایش به تأخیر می‌افتد.

فعالیت JIT

برای بررسی فعالیت جمع‌آوری به‌موقع (JIT) ، فرآیندهای متعلق به برنامه‌تان را گسترش دهید، دو ردیف «Jit Thread Pool» را پیدا کنید و آن‌ها را به بالای نمای خود پین کنید. از آنجایی که این برنامه از نمایه‌های خط پایه در هنگام راه‌اندازی برنامه بهره می‌برد، فعالیت JIT بسیار کمی تا زمانی که اولین فریم ترسیم شود، رخ می‌دهد که با پایان اولین تماس Choreographer.doFrame مشخص می‌شود. با این حال، به دلیل شروع آهسته JIT compiling void توجه کنید، که نشان می دهد فعالیت سیستمی که در طول نقطه ردیابی با برچسب Application creation اتفاق می افتد، باعث ایجاد فعالیت های پس زمینه JIT زیادی می شود. برای حل این مشکل، رویدادهایی را که مدت کوتاهی پس از ترسیم اولین فریم اتفاق می‌افتند، با گسترش مجموعه نمایه به نقطه‌ای که برنامه آماده استفاده است، به نمایه خط پایه اضافه کنید. در بسیاری از موارد، می‌توانید این کار را با افزودن یک خط به انتهای تست ماکرو بنچمارک مجموعه پروفایل پایه خود انجام دهید که منتظر می‌ماند تا ویجت UI خاصی روی صفحه نمایش شما ظاهر شود و نشان می‌دهد که صفحه کاملاً پر شده است.

مخزن رشته‌های Jit با برش «Jit compiling void» برجسته شده است.
شکل 8. اگر فعالیت های JIT زیادی مشاهده کردید، نمایه خط پایه خود را تا جایی گسترش دهید که برنامه آماده استفاده باشد.

نتایج

در نتیجه این تجزیه و تحلیل، تیم Gmail Wear OS پیشرفت های زیر را انجام داد:

  • از آنجایی که در هنگام راه‌اندازی برنامه هنگام مشاهده فعالیت CPU متوجه مشاجره شدند، انیمیشن اسپینر مورد استفاده برای نشان دادن بارگیری برنامه را با یک تصویر ثابت جایگزین کردند. آنها همچنین برای به تعویق انداختن حالت درخشش، دومین حالت صفحه نمایش که برای نشان دادن بارگیری برنامه استفاده می شود، اسپلش صفحه را طولانی کردند تا منابع CPU را آزاد کنند. این تاخیر راه اندازی اپلیکیشن را تا 50 درصد بهبود بخشید.
  • از نگاهی به زمان صرف شده در فعالیت OpenDexFilesFromOat* و JIT، آنها بازنویسی R8 پروفایل های پایه را فعال کردند. این تأخیر راه اندازی برنامه را 20٪ بهبود بخشید.

در اینجا چند نکته از تیم در مورد چگونگی تجزیه و تحلیل کارآمد عملکرد برنامه وجود دارد:

  • یک فرآیند در حال انجام را تنظیم کنید که قادر به جمع آوری خودکار آثار و نتایج باشد. راه اندازی ردیابی خودکار برای برنامه خود را با استفاده از معیارسنجی در نظر بگیرید.
  • از تست A/B برای تغییراتی که فکر می‌کنید شرایط را بهبود می‌بخشد، استفاده کنید و اگر این کار را نکردند، آن‌ها را رد کنید. با استفاده از کتابخانه Macrobenchmark می توانید عملکرد را در سناریوهای مختلف اندازه گیری کنید.

برای کسب اطلاعات بیشتر به منابع زیر مراجعه کنید:

،

راه اندازی برنامه نشان دهنده اولین تاثیر برنامه شما بر روی کاربران است. و کاربران دوست ندارند منتظر بمانند، بنابراین باید مطمئن شوید که برنامه شما سریع شروع می شود. برای اینکه به شما نشان دهیم چگونه یک تیم توسعه برنامه واقعی مشکلات مربوط به راه‌اندازی برنامه خود را پیدا کرده و آنها را تشخیص داده‌اند، تیم Gmail Wear OS چه کاری انجام داد.

تیم Gmail Wear OS یک تلاش بهینه‌سازی را با تمرکز ویژه بر راه‌اندازی برنامه و عملکرد رندر زمان اجرا انجام داد تا معیارهای عملکرد برنامه تیم خود را برآورده کند. با این حال، حتی اگر آستانه خاصی برای هدف گذاری نداشته باشید، اگر کمی برای بررسی آن صرف کنید، تقریباً همیشه فضایی برای بهبود راه اندازی برنامه وجود دارد.

یک ردیابی بگیرید و به راه اندازی برنامه نگاه کنید

برای شروع تجزیه و تحلیل، ردی را ثبت کنید که شامل راه اندازی برنامه برای بررسی دقیق تر در Perfetto یا Android Studio است. این مطالعه موردی از Perfetto استفاده می‌کند زیرا به شما نشان می‌دهد که در سراسر سیستم دستگاه، فراتر از برنامه شما، چه اتفاقی می‌افتد. وقتی ردیابی را در Perfetto آپلود می کنید، به نظر می رسد:

شکل 1. نمای اولیه ردیابی در Perfetto.

از آنجایی که تمرکز بر بهبود راه‌اندازی برنامه است، ردیف را با معیار سفارشی Startups برنامه Android تعیین کنید. پین کردن آن به بالای نمای خود با کلیک کردن روی نماد پین مفید است هنگامی که ماوس را روی ردیف نگه می دارید ظاهر می شود. نوار یا تکه‌ای که در ردیف راه‌اندازی برنامه Android مشاهده می‌کنید، محدوده زمانی را نشان می‌دهد که راه‌اندازی برنامه پوشش می‌دهد، تا زمانی که اولین فریم برنامه روی صفحه کشیده شود، بنابراین باید در آنجا به دنبال مشکلات یا تنگناها بگردید.

ردیف راه‌اندازی برنامه Android با گزینه پین ​​کردن برجسته شده است.
شکل 2. برای تجزیه و تحلیل آسان‌تر، معیار سفارشی Startups برنامه Android را به بالای داشبورد خود پین کنید.

توجه داشته باشید که معیار شروع برنامه اندروید، زمان نمایش اولیه را نشان می‌دهد، حتی اگر از reportFullyDrawn() استفاده می‌کنید. برای شناسایی زمان نمایش کامل ، reportFullyDrawn() را در کادر جستجوی Perfetto جستجو کنید.

موضوع اصلی را بررسی کنید

ابتدا بررسی کنید ببینید در موضوع اصلی چه اتفاقی می افتد. موضوع اصلی بسیار مهم است زیرا معمولاً در آنجاست که تمام رندرهای رابط کاربری در آنجا اتفاق می‌افتد. وقتی مسدود می شود، هیچ ترسیمی نمی تواند اتفاق بیفتد و به نظر می رسد برنامه شما ثابت است. بنابراین می‌خواهید مطمئن شوید که هیچ عملیات طولانی‌مدت در حال اجرا در رشته اصلی انجام نمی‌شود.

برای پیدا کردن رشته اصلی، ردیف را با نام بسته برنامه خود پیدا کنید و آن را گسترش دهید. دو ردیف با همان نام بسته (معمولاً دو ردیف اول در بخش) نشان دهنده موضوع اصلی است. از دو ردیف رشته اصلی، اولین نشان دهنده وضعیت CPU و ردیف دوم نشان دهنده نقاط ردیابی است. دو ردیف رشته اصلی را در زیر متریک راه‌اندازی برنامه Android پین کنید.

راه‌اندازی‌های برنامه Android و ردیف‌های رشته اصلی پین شدند.
شکل 3. ردیف های رشته اصلی را در زیر متریک سفارشی راه اندازی برنامه Android برای کمک به تجزیه و تحلیل پین کنید.

زمان صرف شده در وضعیت قابل اجرا و اختلاف CPU

برای دریافت نمای کلی از فعالیت CPU در هنگام راه‌اندازی برنامه، مکان‌نمای خود را روی رشته اصلی بکشید تا محدوده زمانی راه‌اندازی برنامه را ثبت کنید. پانل Thread States که ظاهر می شود، کل زمان صرف شده در هر وضعیت CPU را در محدوده زمانی انتخابی شما نشان می دهد.

به زمان صرف شده در حالت Runnable نگاه کنید. هنگامی که یک رشته در حالت Runnable است، رشته برای انجام کار در دسترس است اما هیچ کاری برنامه ریزی نشده است. این می تواند نشان دهد که دستگاه تحت بار سنگین است و قادر به برنامه ریزی وظایف با اولویت بالا نیست. برنامه برتر و قابل مشاهده برای کاربر، بالاترین اولویت را در زمان‌بندی دارد، بنابراین یک رشته اصلی بی‌کار اغلب نشان می‌دهد که فرآیندهای فشرده در برنامه شما، مانند رندر کردن انیمیشن، با رشته اصلی برای زمان CPU رقابت می‌کنند.

موضوع اصلی با زمان کل در حالت های مختلف در پانل وضعیت های موضوع برجسته شده است.
شکل 4. زمان نسبی را در حالت های Runnable to Running ارزیابی کنید تا متوجه شوید که چقدر اختلاف CPU وجود دارد.

هر چه نسبت زمان در حالت Runnable به زمان در Running بیشتر باشد، احتمال بروز اختلاف در CPU بیشتر است. هنگام بررسی مشکلات عملکرد به این روش، ابتدا روی طولانی ترین فریم در حال اجرا تمرکز کنید و به سمت موارد کوچکتر کار کنید.

هنگام تجزیه و تحلیل زمان صرف شده در حالت Runnable ، سخت افزار دستگاه را در نظر بگیرید. از آنجایی که برنامه نشان داده شده روی یک دستگاه پوشیدنی با دو CPU اجرا می شود، انتظار می رود زمان بیشتری در حالت Runnable صرف شود و اختلاف CPU بیشتر با سایر فرآیندها نسبت به زمانی که به دستگاهی با CPU بیشتر نگاه کنیم. حتی اگر زمان بیشتری در حالت Runnable بیش از حد انتظار برای یک برنامه تلفن معمولی صرف می شود، ممکن است در زمینه پوشیدنی ها قابل درک باشد.

زمان صرف شده در OpenDexFilesFromOat*

اکنون زمان صرف شده در OpenDexFilesFromOat* را بررسی کنید. در trace، همزمان با برش bindApplication اتفاق می افتد. این برش نشان دهنده زمان صرف شده برای خواندن فایل های DEX برنامه است.

معاملات بایندر مسدود شده است

سپس تراکنش‌های بایندر را بررسی کنید. تراکنش‌های Binder نشان‌دهنده تماس‌های بین کلاینت و سرور است: در این حالت، برنامه (سرویس‌گیر) سیستم اندروید (سرور) را با یک binder transaction فراخوانی می‌کند و سرور با یک binder reply پاسخ می‌دهد. اطمینان حاصل کنید که برنامه در هنگام راه‌اندازی، تراکنش‌های بایندر غیرضروری انجام نمی‌دهد، زیرا خطر اختلاف CPU را افزایش می‌دهند. اگر می‌توانید، کارهایی که شامل تماس‌های بایندر است را به بعد از دوره راه‌اندازی برنامه موکول کنید. اگر باید تراکنش‌های بایندر انجام دهید، مطمئن شوید که بیشتر از نرخ تازه‌سازی Vsync دستگاه شما طول نمی‌کشد.

اولین تراکنش بایندر که معمولاً همزمان با برش ActivityThreadMain انجام می شود، در این مورد بسیار طولانی به نظر می رسد. برای کسب اطلاعات بیشتر در مورد آنچه ممکن است اتفاق بیفتد، این مراحل را دنبال کنید:

  1. برای مشاهده پاسخ مربوط به کلاسور و کسب اطلاعات بیشتر درباره نحوه اولویت بندی تراکنش بایندر، بر روی بخش مورد علاقه تراکنش کلاسور کلیک کنید.
  2. برای مشاهده پاسخ کلاسور، به پنل Current Selection رفته و در قسمت Following threads، روی پاسخ binder کلیک کنید. فیلد Thread همچنین رشته‌ای را به شما می‌گوید که اگر بخواهید به صورت دستی به آنجا بروید، پاسخ binder در آن رخ می‌دهد. در یک روند متفاوت خواهد بود. خطی ظاهر می شود که تراکنش بایندر و پاسخ را به هم متصل می کند.

    یک خط تماس و پاسخ بایندر را متصل می کند.
    شکل 5. تراکنش‌های بایندر را که در حین راه‌اندازی برنامه اتفاق می‌افتند، شناسایی کنید و ارزیابی کنید که آیا می‌توانید آنها را به تعویق بیندازید.
  3. برای اینکه ببینید سرور سیستم چگونه این تراکنش بایندر را مدیریت می کند، رشته های Cpu 0 و Cpu 1 را به بالای صفحه خود پین کنید.

  4. با یافتن برش هایی که شامل نام رشته پاسخ کلاسور هستند، در این مورد "Binder:687_11 [2542]"، فرآیندهای سیستمی را که پاسخ binder را مدیریت می کنند، بیابید. برای دریافت اطلاعات بیشتر در مورد تراکنش بایندر، روی فرآیندهای سیستم مربوطه کلیک کنید.

به این فرآیند سیستمی مرتبط با تراکنش بایندر مورد علاقه که در CPU 0 رخ می دهد، نگاهی بیندازید:

فرآیند سیستم با حالت پایانی «قابل اجرا» (پیش‌گیری).
شکل 6. فرآیند سیستم در حالت Runnable (Preempted) قرار دارد که نشان می دهد با تاخیر مواجه می شود.

حالت پایانی می‌گوید Runnable (Preempted) به این معنی است که فرآیند به تعویق می‌افتد زیرا CPU کار دیگری انجام می‌دهد. برای اینکه بفهمید چه چیزی از آن پیشی گرفته است، ردیف های Ftrace Events را گسترش دهید. در برگه Ftrace Events که در دسترس می‌شود، پیمایش کنید و رویدادهای مربوط به رشته کلاسور مورد علاقه "Binder:687_11 [2542]" را جستجو کنید. در حول و حوش زمانی که فرآیند سیستم از قبل اجرا می‌شود، دو رویداد سرور سیستم که شامل آرگومان "decon" می‌شود، رخ داده است، که به این معنی است که آنها به کنترل‌کننده نمایشگر مرتبط هستند. این منطقی به نظر می رسد زیرا کنترل کننده صفحه نمایش فریم ها را روی صفحه قرار می دهد - یک کار مهم! پس رویدادها را همانطور که هست رها کنید.

رویدادهای FTrace مرتبط با معامله بایندر مورد علاقه برجسته شده است.
شکل 7. رویدادهای FTrace نشان می‌دهد که تراکنش بایندر توسط رویدادهای کنترل‌کننده نمایش به تأخیر می‌افتد.

فعالیت JIT

برای بررسی فعالیت جمع‌آوری به‌موقع (JIT) ، فرآیندهای متعلق به برنامه‌تان را گسترش دهید، دو ردیف «Jit Thread Pool» را پیدا کنید و آن‌ها را به بالای نمای خود پین کنید. از آنجایی که این برنامه از نمایه‌های خط پایه در هنگام راه‌اندازی برنامه بهره می‌برد، فعالیت JIT بسیار کمی تا زمانی که اولین فریم ترسیم شود، رخ می‌دهد که با پایان اولین تماس Choreographer.doFrame مشخص می‌شود. با این حال، به دلیل شروع آهسته JIT compiling void توجه کنید، که نشان می دهد فعالیت سیستمی که در طول نقطه ردیابی با برچسب Application creation اتفاق می افتد، باعث ایجاد فعالیت های پس زمینه JIT زیادی می شود. برای حل این مشکل، رویدادهایی را که مدت کوتاهی پس از ترسیم اولین فریم اتفاق می‌افتند، با گسترش مجموعه نمایه به نقطه‌ای که برنامه آماده استفاده است، به نمایه خط پایه اضافه کنید. در بسیاری از موارد، می‌توانید این کار را با افزودن یک خط به انتهای تست ماکرو بنچمارک مجموعه پروفایل پایه خود انجام دهید که منتظر می‌ماند تا ویجت UI خاصی روی صفحه نمایش شما ظاهر شود و نشان می‌دهد که صفحه کاملاً پر شده است.

مخزن رشته‌های Jit با برش «Jit compiling void» برجسته شده است.
شکل 8. اگر فعالیت های JIT زیادی مشاهده کردید، نمایه خط پایه خود را تا جایی گسترش دهید که برنامه آماده استفاده باشد.

نتایج

در نتیجه این تجزیه و تحلیل، تیم Gmail Wear OS پیشرفت های زیر را انجام داد:

  • از آنجایی که در هنگام راه‌اندازی برنامه هنگام مشاهده فعالیت CPU متوجه مشاجره شدند، انیمیشن اسپینر مورد استفاده برای نشان دادن بارگیری برنامه را با یک تصویر ثابت جایگزین کردند. آنها همچنین برای به تعویق انداختن حالت درخشش، دومین حالت صفحه نمایش که برای نشان دادن بارگیری برنامه استفاده می شود، اسپلش صفحه را طولانی کردند تا منابع CPU را آزاد کنند. این تاخیر راه اندازی اپلیکیشن را تا 50 درصد بهبود بخشید.
  • از نگاهی به زمان صرف شده در فعالیت OpenDexFilesFromOat* و JIT، آنها بازنویسی R8 پروفایل های پایه را فعال کردند. این تأخیر راه اندازی برنامه را 20٪ بهبود بخشید.

در اینجا چند نکته از تیم در مورد چگونگی تجزیه و تحلیل کارآمد عملکرد برنامه وجود دارد:

  • یک فرآیند در حال انجام را تنظیم کنید که قادر به جمع آوری خودکار آثار و نتایج باشد. راه اندازی ردیابی خودکار برای برنامه خود را با استفاده از معیارسنجی در نظر بگیرید.
  • از تست A/B برای تغییراتی که فکر می‌کنید شرایط را بهبود می‌بخشد، استفاده کنید و اگر این کار را نکردند، آن‌ها را رد کنید. با استفاده از کتابخانه Macrobenchmark می توانید عملکرد را در سناریوهای مختلف اندازه گیری کنید.

برای کسب اطلاعات بیشتر به منابع زیر مراجعه کنید:

،

راه اندازی برنامه نشان دهنده اولین تاثیر برنامه شما بر روی کاربران است. و کاربران دوست ندارند منتظر بمانند، بنابراین باید مطمئن شوید که برنامه شما سریع شروع می شود. برای اینکه به شما نشان دهیم چگونه یک تیم توسعه برنامه واقعی مشکلات مربوط به راه‌اندازی برنامه خود را پیدا کرده و آنها را تشخیص داده‌اند، تیم Gmail Wear OS چه کاری انجام داد.

تیم Gmail Wear OS یک تلاش بهینه‌سازی را با تمرکز ویژه بر راه‌اندازی برنامه و عملکرد رندر زمان اجرا انجام داد تا معیارهای عملکرد برنامه تیم خود را برآورده کند. با این حال، حتی اگر آستانه خاصی برای هدف گذاری نداشته باشید، اگر کمی برای بررسی آن صرف کنید، تقریباً همیشه فضایی برای بهبود راه اندازی برنامه وجود دارد.

یک ردیابی بگیرید و به راه اندازی برنامه نگاه کنید

برای شروع تجزیه و تحلیل، ردی را ثبت کنید که شامل راه اندازی برنامه برای بررسی دقیق تر در Perfetto یا Android Studio است. این مطالعه موردی از Perfetto استفاده می‌کند زیرا به شما نشان می‌دهد که در سراسر سیستم دستگاه، فراتر از برنامه شما، چه اتفاقی می‌افتد. وقتی ردیابی را در Perfetto آپلود می کنید، به نظر می رسد:

شکل 1. نمای اولیه ردیابی در Perfetto.

از آنجایی که تمرکز بر بهبود راه‌اندازی برنامه است، ردیف را با معیار سفارشی Startups برنامه Android تعیین کنید. پین کردن آن به بالای نمای خود با کلیک کردن روی نماد پین مفید است هنگامی که ماوس را روی ردیف نگه می دارید ظاهر می شود. نوار یا تکه‌ای که در ردیف راه‌اندازی برنامه Android مشاهده می‌کنید، محدوده زمانی را نشان می‌دهد که راه‌اندازی برنامه پوشش می‌دهد، تا زمانی که اولین فریم برنامه روی صفحه کشیده شود، بنابراین باید در آنجا به دنبال مشکلات یا تنگناها بگردید.

ردیف راه‌اندازی برنامه Android با گزینه پین ​​کردن برجسته شده است.
شکل 2. برای تجزیه و تحلیل آسان‌تر، معیار سفارشی Startups برنامه Android را به بالای داشبورد خود پین کنید.

توجه داشته باشید که معیار شروع برنامه اندروید، زمان نمایش اولیه را نشان می‌دهد، حتی اگر از reportFullyDrawn() استفاده می‌کنید. برای شناسایی زمان نمایش کامل ، reportFullyDrawn() را در کادر جستجوی Perfetto جستجو کنید.

موضوع اصلی را بررسی کنید

ابتدا بررسی کنید ببینید در موضوع اصلی چه اتفاقی می افتد. موضوع اصلی بسیار مهم است زیرا معمولاً در آنجاست که تمام رندرهای رابط کاربری در آنجا اتفاق می‌افتد. وقتی مسدود می شود، هیچ ترسیمی نمی تواند اتفاق بیفتد و به نظر می رسد برنامه شما ثابت است. بنابراین می‌خواهید مطمئن شوید که هیچ عملیات طولانی‌مدت در حال اجرا در رشته اصلی انجام نمی‌شود.

برای پیدا کردن رشته اصلی، ردیف را با نام بسته برنامه خود پیدا کنید و آن را گسترش دهید. دو ردیف با همان نام بسته (معمولاً دو ردیف اول در بخش) نشان دهنده موضوع اصلی است. از دو ردیف رشته اصلی، اولین نشان دهنده وضعیت CPU و ردیف دوم نشان دهنده نقاط ردیابی است. دو ردیف رشته اصلی را در زیر متریک راه‌اندازی برنامه Android پین کنید.

راه‌اندازی‌های برنامه Android و ردیف‌های رشته اصلی پین شدند.
شکل 3. ردیف های رشته اصلی را در زیر متریک سفارشی راه اندازی برنامه Android برای کمک به تجزیه و تحلیل پین کنید.

زمان صرف شده در وضعیت قابل اجرا و اختلاف CPU

برای دریافت نمای کلی از فعالیت CPU در هنگام راه‌اندازی برنامه، مکان‌نمای خود را روی رشته اصلی بکشید تا محدوده زمانی راه‌اندازی برنامه را ثبت کنید. پانل Thread States که ظاهر می شود، کل زمان صرف شده در هر وضعیت CPU را در محدوده زمانی انتخابی شما نشان می دهد.

به زمان صرف شده در حالت Runnable نگاه کنید. هنگامی که یک رشته در حالت Runnable است، رشته برای انجام کار در دسترس است اما هیچ کاری برنامه ریزی نشده است. این می تواند نشان دهد که دستگاه تحت بار سنگین است و قادر به برنامه ریزی وظایف با اولویت بالا نیست. برنامه برتر و قابل مشاهده برای کاربر، بالاترین اولویت را در زمان‌بندی دارد، بنابراین یک رشته اصلی بی‌کار اغلب نشان می‌دهد که فرآیندهای فشرده در برنامه شما، مانند رندر کردن انیمیشن، با رشته اصلی برای زمان CPU رقابت می‌کنند.

موضوع اصلی با زمان کل در حالت های مختلف در پانل وضعیت های موضوع برجسته شده است.
شکل 4. زمان نسبی را در حالت های Runnable to Running ارزیابی کنید تا متوجه شوید که چقدر اختلاف CPU وجود دارد.

هر چه نسبت زمان در حالت Runnable به زمان در Running بیشتر باشد، احتمال بروز اختلاف در CPU بیشتر است. هنگام بررسی مشکلات عملکرد به این روش، ابتدا روی طولانی ترین فریم در حال اجرا تمرکز کنید و به سمت موارد کوچکتر کار کنید.

هنگام تجزیه و تحلیل زمان صرف شده در حالت Runnable ، سخت افزار دستگاه را در نظر بگیرید. از آنجایی که برنامه نشان داده شده روی یک دستگاه پوشیدنی با دو CPU اجرا می شود، انتظار می رود زمان بیشتری در حالت Runnable صرف شود و اختلاف CPU بیشتر با سایر فرآیندها نسبت به زمانی که به دستگاهی با CPU بیشتر نگاه کنیم. حتی اگر زمان بیشتری در حالت Runnable بیش از حد انتظار برای یک برنامه تلفن معمولی صرف می شود، ممکن است در زمینه پوشیدنی ها قابل درک باشد.

زمان صرف شده در OpenDexFilesFromOat*

اکنون زمان صرف شده در OpenDexFilesFromOat* را بررسی کنید. در trace، همزمان با برش bindApplication اتفاق می افتد. این برش نشان دهنده زمان صرف شده برای خواندن فایل های DEX برنامه است.

معاملات بایندر مسدود شده است

سپس تراکنش‌های بایندر را بررسی کنید. تراکنش‌های Binder نشان‌دهنده تماس‌های بین کلاینت و سرور است: در این حالت، برنامه (سرویس‌گیر) سیستم اندروید (سرور) را با یک binder transaction فراخوانی می‌کند و سرور با یک binder reply پاسخ می‌دهد. اطمینان حاصل کنید که برنامه در هنگام راه‌اندازی، تراکنش‌های بایندر غیرضروری انجام نمی‌دهد، زیرا خطر اختلاف CPU را افزایش می‌دهند. اگر می‌توانید، کارهایی که شامل تماس‌های بایندر است را به بعد از دوره راه‌اندازی برنامه موکول کنید. اگر باید تراکنش‌های بایندر انجام دهید، مطمئن شوید که بیشتر از نرخ تازه‌سازی Vsync دستگاه شما طول نمی‌کشد.

اولین تراکنش بایندر که معمولاً همزمان با برش ActivityThreadMain انجام می شود، در این مورد بسیار طولانی به نظر می رسد. برای کسب اطلاعات بیشتر در مورد آنچه ممکن است اتفاق بیفتد، این مراحل را دنبال کنید:

  1. برای مشاهده پاسخ مربوط به کلاسور و کسب اطلاعات بیشتر درباره نحوه اولویت بندی تراکنش بایندر، بر روی بخش مورد علاقه تراکنش کلاسور کلیک کنید.
  2. برای مشاهده پاسخ کلاسور، به پنل Current Selection رفته و در قسمت Following threads، روی پاسخ binder کلیک کنید. فیلد Thread همچنین رشته‌ای را به شما می‌گوید که اگر بخواهید به صورت دستی به آنجا بروید، پاسخ binder در آن رخ می‌دهد. در یک روند متفاوت خواهد بود. خطی ظاهر می شود که تراکنش بایندر و پاسخ را به هم متصل می کند.

    یک خط تماس و پاسخ بایندر را متصل می کند.
    شکل 5. تراکنش‌های بایندر را که در حین راه‌اندازی برنامه اتفاق می‌افتند، شناسایی کنید و ارزیابی کنید که آیا می‌توانید آنها را به تعویق بیندازید.
  3. برای اینکه ببینید سرور سیستم چگونه این تراکنش بایندر را مدیریت می کند، رشته های Cpu 0 و Cpu 1 را به بالای صفحه خود پین کنید.

  4. با یافتن برش هایی که شامل نام رشته پاسخ کلاسور هستند، در این مورد "Binder:687_11 [2542]"، فرآیندهای سیستمی را که پاسخ binder را مدیریت می کنند، بیابید. برای دریافت اطلاعات بیشتر در مورد تراکنش بایندر، روی فرآیندهای سیستم مربوطه کلیک کنید.

به این فرآیند سیستمی مرتبط با تراکنش بایندر مورد علاقه که در CPU 0 رخ می دهد، نگاهی بیندازید:

فرآیند سیستم با حالت پایانی «قابل اجرا» (پیش‌گیری).
شکل 6. فرآیند سیستم در حالت Runnable (Preempted) قرار دارد که نشان می دهد با تاخیر مواجه می شود.

حالت پایانی می‌گوید Runnable (Preempted) به این معنی است که فرآیند به تعویق می‌افتد زیرا CPU کار دیگری انجام می‌دهد. برای اینکه بفهمید چه چیزی از آن پیشی گرفته است، ردیف های Ftrace Events را گسترش دهید. در برگه Ftrace Events که در دسترس می‌شود، پیمایش کنید و رویدادهای مربوط به رشته کلاسور مورد علاقه "Binder:687_11 [2542]" را جستجو کنید. در حول و حوش زمانی که فرآیند سیستم از قبل اجرا می‌شود، دو رویداد سرور سیستم که شامل آرگومان "decon" می‌شود، رخ داده است، که به این معنی است که آنها به کنترل‌کننده نمایشگر مرتبط هستند. این منطقی به نظر می رسد زیرا کنترل کننده صفحه نمایش فریم ها را روی صفحه قرار می دهد - یک کار مهم! پس رویدادها را همانطور که هست رها کنید.

رویدادهای FTrace مرتبط با معامله بایندر مورد علاقه برجسته شده است.
شکل 7. رویدادهای FTrace نشان می‌دهد که تراکنش بایندر توسط رویدادهای کنترل‌کننده نمایش به تأخیر می‌افتد.

فعالیت JIT

برای بررسی فعالیت جمع‌آوری به‌موقع (JIT) ، فرآیندهای متعلق به برنامه‌تان را گسترش دهید، دو ردیف «Jit Thread Pool» را پیدا کنید و آن‌ها را به بالای نمای خود پین کنید. از آنجایی که این برنامه از نمایه‌های خط پایه در هنگام راه‌اندازی برنامه بهره می‌برد، فعالیت JIT بسیار کمی تا زمانی که اولین فریم ترسیم شود، رخ می‌دهد که با پایان اولین تماس Choreographer.doFrame مشخص می‌شود. با این حال، به دلیل شروع آهسته JIT compiling void توجه کنید، که نشان می دهد فعالیت سیستمی که در طول نقطه ردیابی با برچسب Application creation اتفاق می افتد، باعث ایجاد فعالیت های پس زمینه JIT زیادی می شود. برای حل این مشکل، رویدادهایی را که مدت کوتاهی پس از ترسیم اولین فریم اتفاق می‌افتند، با گسترش مجموعه نمایه به نقطه‌ای که برنامه آماده استفاده است، به نمایه خط پایه اضافه کنید. در بسیاری از موارد، می‌توانید این کار را با افزودن یک خط به انتهای تست ماکرو بنچمارک مجموعه پروفایل پایه خود انجام دهید که منتظر می‌ماند تا ویجت UI خاصی روی صفحه نمایش شما ظاهر شود و نشان می‌دهد که صفحه کاملاً پر شده است.

مخزن رشته‌های Jit با برش «Jit compiling void» برجسته شده است.
شکل 8. اگر فعالیت های JIT زیادی مشاهده کردید، نمایه خط پایه خود را تا جایی گسترش دهید که برنامه آماده استفاده باشد.

نتایج

در نتیجه این تجزیه و تحلیل، تیم Gmail Wear OS پیشرفت های زیر را انجام داد:

  • از آنجایی که در هنگام راه‌اندازی برنامه هنگام مشاهده فعالیت CPU متوجه مشاجره شدند، انیمیشن اسپینر مورد استفاده برای نشان دادن بارگیری برنامه را با یک تصویر ثابت جایگزین کردند. آنها همچنین برای به تعویق انداختن حالت درخشش، دومین حالت صفحه نمایش که برای نشان دادن بارگیری برنامه استفاده می شود، اسپلش صفحه را طولانی کردند تا منابع CPU را آزاد کنند. این تاخیر راه اندازی اپلیکیشن را تا 50 درصد بهبود بخشید.
  • از نگاهی به زمان صرف شده در فعالیت OpenDexFilesFromOat* و JIT، آنها بازنویسی R8 پروفایل های پایه را فعال کردند. این تأخیر راه اندازی برنامه را 20٪ بهبود بخشید.

در اینجا چند نکته از تیم در مورد چگونگی تجزیه و تحلیل کارآمد عملکرد برنامه وجود دارد:

  • یک فرآیند در حال انجام را تنظیم کنید که قادر به جمع آوری خودکار آثار و نتایج باشد. راه اندازی ردیابی خودکار برای برنامه خود را با استفاده از معیارسنجی در نظر بگیرید.
  • از تست A/B برای تغییراتی که فکر می‌کنید شرایط را بهبود می‌بخشد، استفاده کنید و اگر این کار را نکردند، آن‌ها را رد کنید. با استفاده از کتابخانه Macrobenchmark می توانید عملکرد را در سناریوهای مختلف اندازه گیری کنید.

برای کسب اطلاعات بیشتر به منابع زیر مراجعه کنید: