แก้ไขข้อบกพร่องของโปรไฟล์พื้นฐาน

เอกสารนี้แสดงแนวทางปฏิบัติแนะนำเพื่อช่วยวิเคราะห์ปัญหาและตรวจสอบว่าโปรไฟล์พื้นฐานทํางานได้อย่างถูกต้องเพื่อให้ได้รับประโยชน์สูงสุด

ปัญหาเกี่ยวกับการสร้าง

หากคุณคัดลอกตัวอย่างโปรไฟล์พื้นฐานในแอปตัวอย่างตอนนี้ใน Android คุณอาจพบปัญหาการทดสอบไม่สำเร็จระหว่างงานโปรไฟล์พื้นฐาน โดยระบุว่าการทดสอบไม่สามารถทำงานบนโปรแกรมจำลองได้

./gradlew assembleDemoRelease
Starting a Gradle Daemon (subsequent builds will be faster)
Calculating task graph as no configuration cache is available for tasks: assembleDemoRelease
Type-safe project accessors is an incubating feature.

> Task :benchmarks:pixel6Api33DemoNonMinifiedReleaseAndroidTest
Starting 14 tests on pixel6Api33

com.google.samples.apps.nowinandroid.foryou.ScrollForYouFeedBenchmark > scrollFeedCompilationNone[pixel6Api33] FAILED
        java.lang.AssertionError: ERRORS (not suppressed): EMULATOR
        WARNINGS (suppressed):
        ...

การทำงานไม่สำเร็จเนื่องจาก Now ใน Android ใช้อุปกรณ์ที่มีการจัดการโดย Gradle ในการสร้างโปรไฟล์พื้นฐาน การทำงานล้มเหลวนั้นเป็นเรื่องปกติ เนื่องจากโดยทั่วไปแล้วคุณไม่ควรทำการทดสอบประสิทธิภาพบนโปรแกรมจำลอง อย่างไรก็ตาม เนื่องจากคุณไม่ได้รวบรวมเมตริกประสิทธิภาพเมื่อสร้างโปรไฟล์พื้นฐาน คุณจึงเรียกใช้การเก็บรวบรวมโปรไฟล์พื้นฐานบนโปรแกรมจำลองได้เพื่อความสะดวก หากต้องการใช้โปรไฟล์พื้นฐานกับโปรแกรมจำลอง ให้สร้างและติดตั้งจากบรรทัดคำสั่ง แล้วตั้งค่าอาร์กิวเมนต์เพื่อเปิดใช้กฎของโปรไฟล์พื้นฐาน ดังนี้

installDemoRelease -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile

หรือคุณจะสร้างการกำหนดค่าการเรียกใช้ที่กำหนดเองใน Android Studio เพื่อเปิดใช้โปรไฟล์พื้นฐานในโปรแกรมจำลองก็ได้ โดยเลือกเรียกใช้ > แก้ไขการกำหนดค่า

เพิ่มการกำหนดค่าการเรียกใช้ที่กำหนดเองเพื่อสร้างโปรไฟล์พื้นฐานใน Now ใน Android
รูปที่ 1 เพิ่มการกำหนดค่าการเรียกใช้ที่กำหนดเองเพื่อสร้างโปรไฟล์พื้นฐานใน "ตอนนี้" บน Android

ปัญหาเกี่ยวกับการติดตั้ง

ตรวจสอบว่า APK หรือ AAB ที่คุณตรวจสอบมาจากตัวแปรของบิลด์ที่มีโปรไฟล์พื้นฐาน ดังนี้

  1. ใน Android Studio ให้เลือกสร้าง > วิเคราะห์ APK
  2. เปิด AAB หรือ APK
  3. หากคุณกำลังตรวจสอบ AAB โปรไฟล์จะอยู่ที่ /BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof หากคุณกำลังตรวจสอบ APK โปรไฟล์จะอยู่ที่ /assets/dexopt/baseline.prof
ตรวจสอบโปรไฟล์พื้นฐานโดยใช้โปรแกรมดู APK ใน Android Studio
รูปที่ 2 ตรวจสอบโปรไฟล์พื้นฐานโดยใช้โปรแกรมดู APK ใน Android Studio

โปรไฟล์พื้นฐานต้องได้รับการคอมไพล์ในอุปกรณ์ที่ใช้แอป เมื่อคุณติดตั้งแอปโดยใช้ Play Store, Android Studio หรือเครื่องมือบรรทัดคำสั่ง Gradle Wrapper การคอมไพล์ในอุปกรณ์จะเกิดขึ้นโดยอัตโนมัติ เมื่อติดตั้งแอปโดยใช้เครื่องมืออื่นๆ คลัง ProfileInstaller ของ Jetpack จะมีหน้าที่จัดคิวโปรไฟล์สำหรับการคอมไพล์ในกระบวนการเพิ่มประสิทธิภาพ DEX เบื้องหลังครั้งถัดไป ในกรณีดังกล่าว หากต้องการให้ระบบใช้โปรไฟล์พื้นฐาน คุณอาจต้องบังคับใช้การคอมไพล์โปรไฟล์พื้นฐาน ProfileVerifier ช่วยให้คุณค้นหาสถานะการติดตั้งและการคอมไพล์โปรไฟล์ได้ ดังที่แสดงในตัวอย่างต่อไปนี้

Kotlin

private const val TAG = "MainActivity"

class MainActivity : ComponentActivity() {
  ...
  override fun onResume() {
    super.onResume()
    lifecycleScope.launch {
      logCompilationStatus()
    }
  }

  private suspend fun logCompilationStatus() {
     withContext(Dispatchers.IO) {
        val status = ProfileVerifier.getCompilationStatusAsync().await()
        when (status.profileInstallResultCode) {
            RESULT_CODE_NO_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Baseline Profile not found")
            RESULT_CODE_COMPILED_WITH_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Compiled with profile")
            RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING ->
                Log.d(TAG, "ProfileInstaller: App was installed through Play store")
            RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST ->
                Log.d(TAG, "ProfileInstaller: PackageName not found")
            RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ ->
                Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read")
            RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE ->
                Log.d(TAG, "ProfileInstaller: Can't write cache file")
            RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            else ->
                Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued")
        }
    }
}

Java

public class MainActivity extends ComponentActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onResume() {
        super.onResume();

        logCompilationStatus();
    }

    private void logCompilationStatus() {
         ListeningExecutorService service = MoreExecutors.listeningDecorator(
                Executors.newSingleThreadExecutor());
        ListenableFuture<ProfileVerifier.CompilationStatus> future =
                ProfileVerifier.getCompilationStatusAsync();
        Futures.addCallback(future, new FutureCallback<>() {
            @Override
            public void onSuccess(CompilationStatus result) {
                int resultCode = result.getProfileInstallResultCode();
                if (resultCode == RESULT_CODE_NO_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Baseline Profile not found");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Compiled with profile");
                } else if (resultCode == RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING) {
                    Log.d(TAG, "ProfileInstaller: App was installed through Play store");
                } else if (resultCode == RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST) {
                    Log.d(TAG, "ProfileInstaller: PackageName not found");
                } else if (resultCode == RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ) {
                    Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read");
                } else if (resultCode
                        == RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE) {
                    Log.d(TAG, "ProfileInstaller: Can't write cache file");
                } else if (resultCode == RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else {
                    Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued");
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d(TAG,
                        "ProfileInstaller: Error getting installation status: " + t.getMessage());
            }
        }, service);
    }
}

รหัสผลลัพธ์ต่อไปนี้ให้คำแนะนำเกี่ยวกับสาเหตุของปัญหาบางอย่าง

RESULT_CODE_COMPILED_WITH_PROFILE
ระบบจะติดตั้ง คอมไพล์ และใช้โปรไฟล์ทุกครั้งที่เรียกใช้แอป นี่เป็นผลการค้นหาที่คุณต้องการเห็น
RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED
ไม่พบโปรไฟล์ใน APK ที่ใช้งานอยู่ ตรวจสอบว่าคุณใช้ตัวแปรรุ่นที่มีโปรไฟล์พื้นฐานหากเห็นข้อผิดพลาดนี้ และ APK มีโปรไฟล์
RESULT_CODE_NO_PROFILE
ไม่มีการติดตั้งโปรไฟล์สำหรับแอปนี้เมื่อติดตั้งแอปผ่าน App Store หรือเครื่องมือจัดการแพ็กเกจ สาเหตุหลักของรหัสข้อผิดพลาดนี้คือโปรแกรมติดตั้งโปรไฟล์ไม่ทํางานเนื่องจากมีการปิดใช้ ProfileInstallerInitializer โปรดทราบว่าเมื่อมีการรายงานข้อผิดพลาดนี้ ระบบจะยังพบโปรไฟล์ที่ฝังอยู่ใน APK ของแอปพลิเคชัน เมื่อไม่พบโปรไฟล์ที่ฝัง รหัสข้อผิดพลาดที่แสดงคือ RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED
RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
พบโปรไฟล์ใน APK หรือ AAB และจัดคิวเพื่อคอมไพล์ เมื่อ ProfileInstaller ติดตั้งโปรไฟล์ ระบบจะจัดคิวโปรไฟล์นั้นไว้สำหรับการคอมไพล์ในครั้งถัดไปที่ระบบเรียกใช้การเพิ่มประสิทธิภาพ DEX ในเบื้องหลัง โปรไฟล์จะไม่ทำงานจนกว่าการคอมไพล์จะเสร็จสมบูรณ์ อย่าพยายามเปรียบเทียบประสิทธิภาพของโปรไฟล์พื้นฐานจนกว่าการคอมไพล์จะเสร็จสมบูรณ์ คุณอาจต้องบังคับให้คอมไพล์โปรไฟล์พื้นฐาน ข้อผิดพลาดนี้จะไม่เกิดขึ้นเมื่อติดตั้งแอปจาก App Store หรือเครื่องมือจัดการแพ็กเกจในอุปกรณ์ที่ใช้ Android 9 (API 28) ขึ้นไป เนื่องจากระบบจะคอมไพล์ระหว่างการติดตั้ง
RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING
มีการติดตั้งโปรไฟล์ที่ไม่ตรงกันและคอมไพล์แอปด้วยโปรไฟล์ดังกล่าว นี่เป็นผลมาจากการติดตั้งผ่าน Google Play Store หรือเครื่องมือจัดการแพ็กเกจ โปรดทราบว่าผลลัพธ์นี้แตกต่างจาก RESULT_CODE_COMPILED_WITH_PROFILE เนื่องจากโปรไฟล์ที่ไม่ตรงกันจะรวบรวมเฉพาะเมธอดที่ยังคงแชร์ระหว่างโปรไฟล์กับแอปเท่านั้น โปรไฟล์จึงมีขนาดเล็กกว่าที่คาดไว้ และระบบจะรวบรวมเมธอดน้อยกว่าที่รวมอยู่ในโปรไฟล์พื้นฐาน
RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE
ProfileVerifier เขียนไฟล์แคชผลการตรวจสอบไม่ได้ ปัญหานี้อาจเกิดขึ้นเนื่องจากสิทธิ์ของโฟลเดอร์แอปไม่ถูกต้อง หรืออุปกรณ์มีพื้นที่ว่างในดิสก์ไม่เพียงพอ
RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION
ProfileVerifieris running on an unsupported API version of Android. ProfileVerifier รองรับเฉพาะ Android 9 (API ระดับ 28) ขึ้นไป
RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST
ระบบจะแสดงข้อผิดพลาด PackageManager.NameNotFoundException เมื่อค้นหาแพ็กเกจแอปใน PackageManager กรณีนี้ควรเกิดขึ้นไม่บ่อยนัก ลองถอนการติดตั้งแอปแล้วติดตั้งทุกอย่างอีกครั้ง
RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ
มีไฟล์แคชผลการตรวจสอบก่อนหน้านี้ แต่อ่านไม่ได้ กรณีนี้ควรเกิดขึ้นน้อยมาก ลองถอนการติดตั้งแอปและติดตั้งทุกอย่างอีกครั้ง

ใช้ ProfileVerifier ในเวอร์ชันที่ใช้งานจริง

ในเวอร์ชันที่ใช้งานจริง คุณสามารถใช้ ProfileVerifier ร่วมกับห้องสมุดการรายงานข้อมูลวิเคราะห์ เช่น Google Analytics สําหรับ Firebase เพื่อสร้างเหตุการณ์การวิเคราะห์ที่ระบุสถานะโปรไฟล์ ตัวอย่างเช่น ฟีเจอร์นี้จะแจ้งเตือนคุณอย่างรวดเร็วหากมีการเผยแพร่แอปเวอร์ชันใหม่ที่ไม่มีโปรไฟล์พื้นฐาน

บังคับใช้การคอมไพล์โปรไฟล์พื้นฐาน

หากสถานะการคอมไพล์ของโปรไฟล์พื้นฐานคือRESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION คุณสามารถบังคับให้คอมไพล์ทันทีได้โดยใช้ adb โดยทําดังนี้

adb shell cmd package compile -r bg-dexopt PACKAGE_NAME

ตรวจสอบสถานะการคอมไพล์โดยไม่ใช้ ProfileVerifier

หากไม่ได้ใช้ ProfileVerifier คุณสามารถตรวจสอบสถานะการคอมไพล์ได้โดยใช้ adb แม้ว่าจะไม่ให้ข้อมูลเชิงลึกที่ลึกซึ้งเท่ากับ ProfileVerifier ก็ตาม

adb shell dumpsys package dexopt | grep -A 2 PACKAGE_NAME

การใช้ adb จะสร้างผลลัพธ์ที่คล้ายกับตัวอย่างต่อไปนี้

  [com.google.samples.apps.nowinandroid.demo]
    path: /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/base.apk
      arm64: [status=speed-profile] [reason=bg-dexopt] [primary-abi]
        [location is /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/oat/arm64/base.odex]

ค่าสถานะจะระบุสถานะการคอมไพล์โปรไฟล์ และเป็นค่าใดค่าหนึ่งต่อไปนี้

สถานะการคอมไพล์ ความหมาย
speed‑profile มีโปรไฟล์ที่คอมไพล์แล้วและมีการใช้งาน
verify ไม่มีโปรไฟล์ที่คอมไพล์ไว้

สถานะ verify ไม่ได้หมายความว่า APK หรือ AAB ไม่มีโปรไฟล์ เนื่องจากระบบอาจจัดคิวการคอมไพล์ไว้สำหรับงานการเพิ่มประสิทธิภาพ DEX ในเบื้องหลังครั้งถัดไป

ค่าเหตุผลจะระบุสิ่งที่ทริกเกอร์การคอมไพล์โปรไฟล์ และเป็นค่าใดค่าหนึ่งต่อไปนี้

เหตุผล ความหมาย
install‑dm โปรไฟล์พื้นฐานได้รับการคอมไพล์โดย Google Play หรือคุณด้วยตนเองเมื่อติดตั้งแอป
bg‑dexopt คอมไพล์โปรไฟล์ขณะที่อุปกรณ์ไม่มีการใช้งาน ซึ่งอาจเป็นโปรไฟล์พื้นฐานหรืออาจเป็นโปรไฟล์ที่รวบรวมระหว่างการใช้งานแอป
cmdline การคอมไพล์ทริกเกอร์โดยใช้ adb ซึ่งอาจเป็นโปรไฟล์พื้นฐานหรืออาจเป็นโปรไฟล์ที่รวบรวมระหว่างการใช้งานแอป

ปัญหาด้านประสิทธิภาพ

ส่วนนี้จะแสดงแนวทางปฏิบัติแนะนำในการกําหนดและเปรียบเทียบโปรไฟล์พื้นฐานอย่างถูกต้องเพื่อให้ได้รับประโยชน์สูงสุด

เปรียบเทียบเมตริกการเริ่มต้นอย่างถูกต้อง

โปรไฟล์พื้นฐานจะมีประสิทธิภาพมากขึ้นหากเมตริกการเริ่มต้นใช้งานได้รับการกําหนดไว้อย่างดี เมตริกหลัก 2 รายการ ได้แก่ เวลาที่ใช้ในการเริ่มแสดงผล (TTID) และเวลาที่ใช้ในการแสดงผลครบถ้วน (TTFD)

TTID คือเวลาที่แอปวาดเฟรมแรก สิ่งสำคัญคือต้องทำให้ข้อความนี้สั้นที่สุดเท่าที่จะทำได้ เนื่องจากการแสดงข้อความจะบอกให้ผู้ใช้ทราบว่าแอปทำงานอยู่ คุณยังแสดงตัวบ่งชี้ความคืบหน้าที่ไม่แน่นอนเพื่อแสดงให้เห็นว่าแอปตอบสนองได้อีกด้วย

TTFD คือเวลาที่ผู้ใช้โต้ตอบกับแอปได้จริง คุณควรทำให้ข้อความนี้สั้นที่สุดเพื่อไม่ให้ผู้ใช้หงุดหงิด หากส่งสัญญาณ TTFD อย่างถูกต้อง แสดงว่าคุณบอกระบบว่าโค้ดที่ทำงานระหว่างทางไปยัง TTFD เป็นส่วนหนึ่งของการเริ่มต้นแอป ระบบจึงมีแนวโน้มที่จะวางโค้ดนี้ในโปรไฟล์

รักษาทั้ง TTID และ TTFD ให้ต่ำที่สุดเพื่อให้แอปตอบสนองได้อย่างรวดเร็ว

ระบบสามารถตรวจหา TTID, แสดงใน Logcat และรายงานเป็นส่วนหนึ่งของการเปรียบเทียบประสิทธิภาพการเริ่มต้น อย่างไรก็ตาม ระบบไม่สามารถระบุ TTFD ได้ และแอปมีหน้าที่รับผิดชอบในการรายงานเมื่อถึงสถานะการโต้ตอบที่วาดเสร็จสมบูรณ์ ซึ่งทำได้ด้วยการเรียกใช้ reportFullyDrawn() หรือ ReportDrawn หากคุณใช้ Jetpack Compose หากมีงานเบื้องหลังหลายรายการที่ต้องดำเนินการให้เสร็จสมบูรณ์ก่อนที่ระบบจะถือว่าแอปวาดภาพเสร็จแล้ว คุณสามารถใช้ FullyDrawnReporter ตามที่อธิบายไว้ในปรับปรุงความแม่นยำของเวลาเริ่มต้น

โปรไฟล์คลังภาพและโปรไฟล์ที่กำหนดเอง

เมื่อทำการเปรียบเทียบผลลัพธ์ของโปรไฟล์ คุณอาจแยกประโยชน์ของโปรไฟล์แอปออกจากโปรไฟล์ที่มาจากไลบรารี เช่น ไลบรารี Jetpack ได้ยาก เมื่อคุณสร้าง APK ปลั๊กอิน Android Gradle จะเพิ่มโปรไฟล์ในทรัพยากร Dependency ของไลบรารี รวมถึงโปรไฟล์ที่กำหนดเอง วิธีนี้เหมาะสําหรับการเพิ่มประสิทธิภาพโดยรวมและแนะนําสําหรับบิลด์รุ่น อย่างไรก็ตาม ข้อมูลนี้ทำให้วัดประสิทธิภาพที่เพิ่มขึ้นจากโปรไฟล์ที่กำหนดเองได้ยาก

วิธีรวดเร็วในการดูการเพิ่มประสิทธิภาพเพิ่มเติมที่โปรไฟล์ที่กำหนดเองมอบให้ด้วยตนเองคือนำโปรไฟล์นั้นออก แล้วเรียกใช้การเปรียบเทียบ จากนั้นเปลี่ยนแบตเตอรี่และทำการทดสอบประสิทธิภาพอีกครั้ง การเปรียบเทียบ 2 รายการนี้จะแสดงการเพิ่มประสิทธิภาพที่ได้จากโปรไฟล์คลังเพียงอย่างเดียว และโปรไฟล์คลังบวกกับโปรไฟล์ที่กำหนดเอง

วิธีเปรียบเทียบโปรไฟล์แบบอัตโนมัติคือการสร้างตัวแปรบิลด์ใหม่ที่มีเฉพาะโปรไฟล์คลัง และไม่รวมโปรไฟล์ที่กำหนดเอง เปรียบเทียบการเปรียบเทียบจากตัวแปรนี้กับตัวแปรรุ่นที่มีทั้งโปรไฟล์คลังภาพและโปรไฟล์ที่กําหนดเอง ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าตัวแปรที่มีเฉพาะโปรไฟล์คลัง เพิ่มตัวแปรใหม่ชื่อ releaseWithoutCustomProfile ลงในโมดูลผู้บริโภคโปรไฟล์ ซึ่งโดยปกติแล้วคือโมดูลแอป

Kotlin

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    create("releaseWithoutCustomProfile") {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile(project(":baselineprofile"))
}

baselineProfile {
  variants {
    create("release") {
      from(project(":baselineprofile"))
    }
  }
}

Groovy

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    releaseWithoutCustomProfile {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile ':baselineprofile"'
}

baselineProfile {
  variants {
    release {
      from(project(":baselineprofile"))
    }
  }
}

ตัวอย่างโค้ดก่อนหน้านี้จะนำการพึ่งพา baselineProfile ออกจากตัวแปรทั้งหมด และใช้กับตัวแปร release เท่านั้น การดำเนินการนี้อาจดูขัดแย้งกับหลักการที่ว่าระบบยังคงเพิ่มโปรไฟล์คลังเมื่อนำการพึ่งพาโมดูลเครื่องมือสร้างโปรไฟล์ออกแล้ว อย่างไรก็ตาม โมดูลนี้มีหน้าที่รับผิดชอบต่อการสร้างโปรไฟล์ที่กำหนดเองเท่านั้น ปลั๊กอิน Android Gradle จะยังคงทำงานสำหรับตัวแปรทั้งหมดและมีหน้าที่รับผิดชอบในการรวมโปรไฟล์ไลบรารี

นอกจากนี้ คุณยังต้องเพิ่มตัวแปรใหม่ลงในโมดูลเครื่องมือสร้างโปรไฟล์ด้วย ในตัวอย่างนี้ โมดูลโปรดิวเซอร์มีชื่อว่า :baselineprofile

Kotlin

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      create("releaseWithoutCustomProfile") {}
      ...
    }
  ...
}

Groovy

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      releaseWithoutCustomProfile {}
      ...
    }
  ...
}

เมื่อเรียกใช้การเปรียบเทียบประสิทธิภาพจาก Android Studio ให้เลือกตัวแปร releaseWithoutCustomProfile เพื่อวัดประสิทธิภาพด้วยโปรไฟล์ไลบรารีเท่านั้น หรือเลือกตัวแปร release เพื่อวัดประสิทธิภาพด้วยโปรไฟล์ไลบรารีและโปรไฟล์ที่กำหนดเอง

หลีกเลี่ยงการเริ่มต้นแอปที่กําหนดค่าไว้สำหรับ I/O

หากแอปเรียกใช้ I/O หรือเรียกใช้เครือข่ายจํานวนมากระหว่างการเริ่มต้น อาจส่งผลเสียต่อทั้งเวลาเริ่มต้นของแอปและความแม่นยําของข้อมูลการเปรียบเทียบประสิทธิภาพการเริ่มต้น การเรียกใช้ที่หนักหน่วงเหล่านี้อาจใช้เวลาไม่แน่นอน ซึ่งอาจแตกต่างกันไปเมื่อเวลาผ่านไปและแม้กระทั่งระหว่างการเรียกใช้การเปรียบเทียบเดียวกันซ้ำๆ โดยทั่วไปแล้วการเรียกใช้ I/O จะดีกว่าการเรียกใช้เครือข่าย เนื่องจากการเรียกใช้เครือข่ายอาจได้รับผลกระทบจากปัจจัยภายนอกและภายในอุปกรณ์ หลีกเลี่ยงการเรียกใช้เครือข่ายระหว่างการเริ่มต้น หากหลีกเลี่ยงการใช้อย่างใดอย่างหนึ่งไม่ได้ ให้ใช้ I/O

เราขอแนะนำให้ทำให้สถาปัตยกรรมแอปรองรับการเริ่มต้นแอปโดยไม่ต้องมีการเรียกใช้เครือข่ายหรือ I/O แม้ว่าจะใช้ก็ต่อเมื่อทำการเปรียบเทียบประสิทธิภาพการเริ่มต้นเท่านั้น วิธีนี้ช่วยให้มั่นใจได้ว่าการทดสอบซ้ำต่างๆ ของข้อมูลเปรียบเทียบจะมีความแปรปรวนต่ำที่สุด

หากแอปใช้ Hilt คุณสามารถระบุการใช้งานแบบจํากัด I/O จําลองเมื่อทำการทดสอบประสิทธิภาพในการทดสอบประสิทธิภาพระดับไมโครและ Hilt

ครอบคลุมเส้นทางของผู้ใช้ที่สําคัญทั้งหมด

คุณต้องครอบคลุมเส้นทางของผู้ใช้ที่สําคัญทั้งหมดอย่างถูกต้องในการสร้างโปรไฟล์พื้นฐาน โปรไฟล์พื้นฐานจะไม่ปรับปรุงเส้นทางของผู้ใช้ที่ไม่ได้ครอบคลุม โปรไฟล์พื้นฐานที่มีประสิทธิภาพมากที่สุดจะรวมเส้นทางการเข้าชมทั่วไปทั้งหมดของผู้ใช้ที่เริ่มต้นใช้งาน รวมถึงเส้นทางการเข้าชมในแอปที่ไวต่อประสิทธิภาพ เช่น การเลื่อนดูรายการ