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

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

ปัญหาเกี่ยวกับบิลด์

หากคุณได้คัดลอกตัวอย่างโปรไฟล์พื้นฐานใน Now in 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 เพิ่มการกำหนดค่าการเรียกใช้ที่กำหนดเองเพื่อสร้างเกณฑ์พื้นฐาน โปรไฟล์ใน Now บน Android

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

ตรวจสอบว่า APK หรือ AAB ที่คุณกำลังสร้างนั้นมาจากตัวแปรบิลด์ที่มี โปรไฟล์พื้นฐาน วิธีที่ง่ายที่สุดในการตรวจสอบคือเปิด APK ใน Android Studio โดยเลือก สร้าง > วิเคราะห์ APK กำลังเปิด APK และกำลังค้นหาโปรไฟล์ใน /assets/dexopt/baseline.prof ไฟล์:

วันที่ ตรวจสอบโปรไฟล์พื้นฐานโดยใช้โปรแกรมดู APK ใน Android Studio
รูปที่ 2 ตรวจสอบโปรไฟล์พื้นฐานโดยใช้โปรแกรมดู APK ใน Android Studio

ต้องคอมไพล์โปรไฟล์พื้นฐานในอุปกรณ์ที่ใช้แอป สำหรับทั้ง 2 กลุ่ม การติดตั้งแอปใน App Store และแอปที่ติดตั้งโดยใช้ PackageInstaller การคอมไพล์ในอุปกรณ์จะเกิดขึ้นโดยเป็นส่วนหนึ่งของแอป ขั้นตอนการติดตั้ง แต่เมื่อแอปโหลดจากแหล่งที่ไม่รู้จักจาก Android Studio หรือ โดยใช้เครื่องมือบรรทัดคำสั่ง ไลบรารี Jetpack ProfileInstaller ซึ่งมีหน้าที่จัดคิวโปรไฟล์สำหรับการคอมไพล์ในช่วงถัดไป ของกระบวนการเพิ่มประสิทธิภาพ 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 หรือ AAB ที่เรียกใช้ ตรวจสอบว่าคุณใช้ สร้างตัวแปรที่มีโปรไฟล์พื้นฐาน หากคุณเห็นข้อผิดพลาดนี้ APK มีโปรไฟล์
RESULT_CODE_NO_PROFILE
ไม่ได้ติดตั้งโปรไฟล์สำหรับแอปนี้ขณะติดตั้งแอปผ่านแอป ตัวจัดการร้านค้าหรือแพ็กเกจ สาเหตุหลักสำหรับรหัสข้อผิดพลาดคือโปรไฟล์ โปรแกรมติดตั้งไม่ทำงานเนื่องจากปิดใช้ 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 เล่นเมื่อติดตั้งแอปแล้ว
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 ของไลบรารีและโปรไฟล์ที่คุณกำหนดเอง ข้อมูลถูกต้อง เพื่อเพิ่มประสิทธิภาพโดยรวม และแนะนำสำหรับบิลด์ของคุณ อย่างไรก็ตาม การวัดประสิทธิภาพที่เพิ่มขึ้นมานั้นทำได้ยาก จากโปรไฟล์ที่กำหนดเองของคุณ

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

วิธีเปรียบเทียบโปรไฟล์แบบอัตโนมัติคือการสร้างตัวแปรบิลด์ใหม่ จะมีเพียงโปรไฟล์ไลบรารีเท่านั้น และไม่มีโปรไฟล์ที่กำหนดเองของคุณ เปรียบเทียบ การเปรียบเทียบจากตัวแปรนี้กับตัวแปรการเปิดตัวที่มีทั้ง โปรไฟล์ไลบรารีและโปรไฟล์ที่กำหนดเองของคุณ ตัวอย่างต่อไปนี้จะแสดงวิธีการ เพื่อตั้งค่าตัวแปรที่มีเฉพาะโปรไฟล์ไลบรารี เพิ่มตัวแปรใหม่ ตั้งชื่อ 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"))
    }
  }
}

ดึงดูด

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

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

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

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

Kotlin

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

ดึงดูด

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

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

หลีกเลี่ยงการเริ่มต้นแอปที่เชื่อมโยงกับ I/O

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

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

หากแอปใช้ Hilt คุณสามารถใส่ I/O-bound ปลอมได้ ที่ใช้เมื่อเปรียบเทียบใน Microbenchmark และ Hilt

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

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