เขียนการเปรียบเทียบมาโคร

ใช้ไลบรารี Macrobenchmark เพื่อทดสอบกรณีการใช้งานที่ใหญ่ขึ้นของแอป รวมถึงการเริ่มต้นแอปและการจัดการ UI ที่ซับซ้อน เช่น การเลื่อน RecyclerView หรือการเรียกใช้ภาพเคลื่อนไหว หากต้องการทดสอบส่วนเล็กๆ ของโค้ด โปรดดูไลบรารี Microbenchmark หน้านี้แสดงวิธีตั้งค่า ไลบรารี Macrobenchmark

ไลบรารีจะแสดงผลการเปรียบเทียบไปยังทั้งคอนโซล Android Studio และ ไฟล์ JSON ที่มีรายละเอียดเพิ่มเติม นอกจากนี้ ยังมีไฟล์การติดตามที่คุณโหลดและ วิเคราะห์ใน Android Studio ได้ด้วย

ใช้ไลบรารี Macrobenchmark ในสภาพแวดล้อมการรวมอย่างต่อเนื่อง (CI) ตามที่อธิบายไว้ในการทดสอบประสิทธิภาพในการรวมอย่างต่อเนื่อง

คุณใช้ Macrobenchmark เพื่อสร้างโปรไฟล์พื้นฐานได้ ก่อนอื่น ให้ตั้งค่า ไลบรารี Macrobenchmark จากนั้นคุณจะสร้าง Baseline Profile ได้

การตั้งค่าโปรเจ็กต์

เราขอแนะนำให้คุณใช้ Macrobenchmark กับ Android Studio เวอร์ชันล่าสุด สำหรับฟีเจอร์ของ IDE ที่ผสานรวมกับ Macrobenchmark

ตั้งค่าโมดูล Macrobenchmark

Macrobenchmark ต้องใช้ com.android.test โมดูลที่แยกจากโค้ดของแอป ซึ่งมีหน้าที่เรียกใช้การทดสอบ ที่วัดแอป

ใน Android Studio มีเทมเพลตที่ช่วยลดความซับซ้อนในการตั้งค่าโมดูล Macrobenchmark เทมเพลตโมดูลการเปรียบเทียบจะสร้างโมดูลในโปรเจ็กต์โดยอัตโนมัติ เพื่อวัดแอปที่สร้างโดยโมดูลแอป รวมถึงการเปรียบเทียบการเริ่มต้นตัวอย่าง

หากต้องการใช้เทมเพลตโมดูลเพื่อสร้างโมดูลใหม่ ให้ทำดังนี้

  1. คลิกขวาที่โปรเจ็กต์หรือโมดูลในแผงโปรเจ็กต์ใน Android Studio แล้วเลือกใหม่ > โมดูล

  2. เลือกการเปรียบเทียบจากแผงเทมเพลต คุณปรับแต่ง แอปเป้าหมาย ซึ่งหมายถึงแอปที่จะใช้เปรียบเทียบ รวมถึงชื่อแพ็กเกจและโมดูล สำหรับโมดูล Macrobenchmark ใหม่ได้

  3. คลิกเสร็จสิ้น

เทมเพลตโมดูลการเปรียบเทียบ

รูปที่ 1 เทมเพลตโมดูลการเปรียบเทียบ

ตั้งค่าแอป

หากต้องการเปรียบเทียบประสิทธิภาพของแอป ซึ่งเรียกว่าเป้าหมายของ Macrobenchmark แอปจะต้องprofileable ซึ่งจะช่วยให้อ่านข้อมูลการติดตามโดยละเอียดได้โดยไม่ส่งผลต่อประสิทธิภาพ วิซาร์ดโมดูลจะเพิ่มแท็ก <profileable> ลงในไฟล์ AndroidManifest.xml ของแอปโดยอัตโนมัติ

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

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

Kotlin

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
    }

    create("benchmark") {
        initWith(getByName("release"))
        signingConfig = signingConfigs.getByName("debug")
    }
}

Groovy

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "keep-rules.pro"
        )
        // In real app, this would use its own release keystore
        signingConfig = signingConfigs.getByName("debug")
        baselineProfile.automaticGenerationDuringBuild = true
    }
}

เพื่อให้แน่ใจว่าการเรียกใช้การเปรียบเทียบจะสร้างและทดสอบตัวแปรที่ถูกต้องของแอป ดังที่แสดงในรูปที่ 2 ให้ทำดังนี้

  1. ทำการซิงค์ Gradle
  2. เปิดแผงตัวแปรบิลด์
  3. เลือกตัวแปรเกณฑ์เปรียบเทียบของทั้งแอปและโมดูล Macrobenchmark

เลือกการเปรียบเทียบ
ตัวแปร

รูปที่ 2 เลือกรูปแบบการเปรียบเทียบ

(ไม่บังคับ) ตั้งค่าแอปแบบหลายโมดูล

หากแอปมีโมดูล Gradle มากกว่า 1 โมดูล ให้ตรวจสอบว่าสคริปต์บิลด์ทราบ ว่าควรคอมไพล์ตัวแปรบิลด์ใด เพิ่มพร็อพเพอร์ตี้ matchingFallbacks ลงใน benchmark ประเภทบิลด์ของโมดูล :macrobenchmark และ :app โมดูล Gradle ที่เหลือจะมีการกำหนดค่าเหมือนเดิมได้

Kotlin

create("benchmark") {
    initWith(getByName("release"))
    signingConfig = signingConfigs.getByName("debug")

    matchingFallbacks += listOf("release")
 }

Groovy

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug

    matchingFallbacks = ['release']
 }

หากไม่มีการดำเนินการนี้ benchmark ประเภทบิลด์ที่เพิ่มใหม่จะทำให้บิลด์ล้มเหลว และแสดงข้อความแสดงข้อผิดพลาดต่อไปนี้

> Could not resolve project :shared.
     Required by:
         project :app
      > No matching variant of project :shared was found.
      ...

เมื่อเลือกตัวแปรบิลด์ในโปรเจ็กต์ ให้เลือก benchmark สำหรับโมดูล :app และ :macrobenchmark และเลือก release สำหรับโมดูลอื่นๆ ที่คุณมีใน แอป ดังที่แสดงในรูปที่ 3

เปรียบเทียบประสิทธิภาพของตัวแปรสำหรับโปรเจ็กต์แบบหลายโมดูลที่มีประเภทบิลด์สำหรับการเผยแพร่และเปรียบเทียบประสิทธิภาพ
ที่เลือก

รูปที่ 3 ตัวแปรการเปรียบเทียบสำหรับโปรเจ็กต์แบบหลายโมดูลที่มีการเลือกประเภทบิลด์การเผยแพร่และ การเปรียบเทียบ

ดูข้อมูลเพิ่มเติมได้ที่ใช้การจัดการการขึ้นต่อกันที่รับรู้ถึงตัวแปร

(ไม่บังคับ) ตั้งค่าผลิตภัณฑ์ย่อย

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

ตัวอย่างในหน้านี้ใช้ 2 รสชาติของผลิตภัณฑ์ในโมดูล :app demo และ production ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
        // ...
    }
    create("production") {
        dimension = "environment"
        // ...
    }
}

Groovy

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
        // ...
    }

    production {
        dimension 'environment'
        // ...
    }
}

หากไม่มีการกำหนดค่านี้ คุณอาจได้รับข้อผิดพลาดในการสร้างที่คล้ายกับการมีโมดูล Gradle หลายโมดูล ดังนี้

Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
   > Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
      > Could not resolve project :app.
        Required by:
            project :macrobenchmark
         > The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
             -   demoBenchmarkRuntimeElements
             -   productionBenchmarkRuntimeElements
           All of them match the consumer attributes:
           ...

2 ส่วนต่อไปนี้เป็นวิธีในการกำหนดค่าการเปรียบเทียบกับผลิตภัณฑ์หลายรุ่น

ใช้ missingDimensionStrategy

การระบุ missingDimensionStrategy ใน defaultConfig ของโมดูล :macrobenchmark จะบอกให้ระบบบิลด์กลับไปใช้มิติข้อมูลรสชาติ ระบุว่าควรใช้มิติข้อมูลใดหากไม่พบในโมดูล ในตัวอย่างต่อไปนี้ ระบบจะใช้productionเป็นมิติข้อมูลเริ่มต้น

Kotlin

defaultConfig {
    missingDimensionStrategy("environment", "production")
}

Groovy

defaultConfig {
    missingDimensionStrategy "environment", "production"
}

ด้วยวิธีนี้ :macrobenchmark โมดูลจะสร้างและเปรียบเทียบเฉพาะ รสชาติของผลิตภัณฑ์ที่ระบุ ซึ่งจะเป็นประโยชน์หากคุณทราบว่ามีรสชาติของผลิตภัณฑ์เพียงรสชาติเดียว ที่มีการกำหนดค่าที่เหมาะสมสำหรับการเปรียบเทียบ

กำหนด Product Flavor ในโมดูล :macrobenchmark

หากต้องการสร้างและเปรียบเทียบผลิตภัณฑ์อื่นๆ ให้กำหนดผลิตภัณฑ์เหล่านั้นในโมดูล :macrobenchmark ระบุในลักษณะเดียวกับในโมดูล :app แต่กำหนด productFlavors ให้กับ dimension เท่านั้น ไม่ต้องตั้งค่าอื่นๆ

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
    }
    create("production") {
        dimension = "environment"
    }
}

Groovy

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
    }

    production {
        dimension 'environment'
    }
}

หลังจากกำหนดและซิงค์โปรเจ็กต์แล้ว ให้เลือกตัวแปรบิลด์ที่เกี่ยวข้องจากแผงตัวแปรบิลด์ ดังที่แสดงในรูปที่ 4

รูปแบบการเปรียบเทียบสำหรับโปรเจ็กต์ที่มีรสชาติของผลิตภัณฑ์ที่แสดง
productionBenchmark และ release
ที่เลือก

รูปที่ 4 เปรียบเทียบตัวแปรสำหรับโปรเจ็กต์โดยแสดงรสชาติของผลิตภัณฑ์ที่เลือก "productionBenchmark" และ "release"

ดูข้อมูลเพิ่มเติมได้ที่แก้ไขข้อผิดพลาดในการสร้างที่เกี่ยวข้องกับการจับคู่ตัวแปร

สร้างคลาส Macrobenchmark

การทดสอบเปรียบเทียบมีให้ใช้งานผ่านMacrobenchmarkRule กฎ JUnit4 API ในไลบรารี Macrobenchmark ซึ่งมีเมธอด measureRepeated ที่ช่วยให้คุณระบุเงื่อนไขต่างๆ เกี่ยวกับวิธีเรียกใช้และเปรียบเทียบแอปเป้าหมายได้

คุณต้องระบุอย่างน้อย packageName ของแอปเป้าหมาย metrics ที่ต้องการวัด และจำนวน iterations ที่ต้องใช้ในการเปรียบเทียบ

Kotlin

@LargeTest
@RunWith(AndroidJUnit4::class)
class SampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = TARGET_PACKAGE,
        metrics = listOf(StartupTimingMetric()),
        iterations = DEFAULT_ITERATIONS,
    ) {
        // starts default launch activity
        uiAutomator { startApp(TARGET_PACKAGE) }
    }
}

Java

@LargeTest
@RunWith(AndroidJUnit4.class)
public class SampleStartupBenchmark {
    @Rule
    public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule();

    @Test
    public void startup() {
        benchmarkRule.measureRepeated(
            /* packageName */ TARGET_PACKAGE,
            /* metrics */ Arrays.asList(new StartupTimingMetric()),
            /* iterations */ 5,
            /* measureBlock */ scope -> {
                // starts default launch activity
                scope.startActivityAndWait();
                return Unit.INSTANCE;
            }
        );
    }
}

ดูตัวเลือกทั้งหมดในการปรับแต่งการเปรียบเทียบได้ที่ส่วนปรับแต่งการเปรียบเทียบ

เรียกใช้การเปรียบเทียบ

เรียกใช้การทดสอบจากภายใน Android Studio เพื่อวัดประสิทธิภาพของแอป ในอุปกรณ์ คุณสามารถเรียกใช้การทดสอบประสิทธิภาพได้ในลักษณะเดียวกับการเรียกใช้ @Test อื่นๆ โดยใช้การดำเนินการที่ขอบข้างคลาสหรือเมธอดทดสอบ ดังที่แสดงใน รูปที่ 5

เรียกใช้ Macrobenchmark ด้วยการดำเนินการที่ขอบถัดจากคลาส test

รูปที่ 5 เรียกใช้ Macrobenchmark ด้วยการดำเนินการที่ขอบข้างคลาสการทดสอบ

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

./gradlew :macrobenchmark:connectedCheck

คุณเรียกใช้การทดสอบเดียวได้โดยการดำเนินการต่อไปนี้

./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup

ดูข้อมูลเกี่ยวกับวิธีเรียกใช้และตรวจสอบการเปรียบเทียบในการผสานรวมอย่างต่อเนื่องได้ที่การเปรียบเทียบในการผสานรวมอย่างต่อเนื่อง

ผลการเปรียบเทียบ

หลังจากเรียกใช้การเปรียบเทียบสำเร็จแล้ว ระบบจะแสดงเมตริกใน Android Studio โดยตรงและส่งออกสำหรับการใช้งาน CI ในไฟล์ JSON การทำซ้ำที่วัดได้แต่ละครั้ง จะบันทึกการติดตามระบบแยกกัน คุณเปิดผลการติดตามเหล่านี้ได้โดยคลิกลิงก์ในแผงผลการทดสอบ ดังที่แสดงในรูปที่ 6

ผลการทดสอบมาโครเบนช์มาร์ก

รูปที่ 6 ผลการเริ่มต้นของมาโครเบนช์มาร์ก

เมื่อโหลดการติดตามแล้ว Android Studio จะแจ้งให้คุณเลือกกระบวนการที่จะ วิเคราะห์ ระบบจะป้อนข้อมูลการเลือกไว้ล่วงหน้าด้วยกระบวนการของแอปเป้าหมาย ดังที่แสดงใน รูปที่ 7

กระบวนการติดตาม Studio
การเลือก

รูปที่ 7 การเลือกกระบวนการติดตามใน Studio

หลังจากโหลดไฟล์การติดตามแล้ว Studio จะแสดงผลลัพธ์ในเครื่องมือ โปรไฟล์ CPU ดังนี้

Studio
Trace

รูปที่ 8 การติดตามของ Studio

ระบบจะคัดลอกรายงาน JSON และการติดตามการจัดทำโปรไฟล์จาก อุปกรณ์ไปยังโฮสต์โดยอัตโนมัติด้วย โดยจะเขียนในเครื่องโฮสต์ในตำแหน่งต่อไปนี้

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/

เข้าถึงไฟล์การย้ายข้อมูลด้วยตนเอง

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

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

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace

เมื่อมีไฟล์การติดตามในระบบโฮสต์แล้ว คุณจะเปิดไฟล์ดังกล่าวใน Android Studio ได้โดยไปที่File > Open ในเมนู ซึ่งแสดงมุมมองเครื่องมือโปรไฟล์ที่แสดง ในส่วนก่อนหน้า

ข้อผิดพลาดในการกำหนดค่า

หากกำหนดค่าแอปไม่ถูกต้อง (ดีบักได้หรือโปรไฟล์ไม่ได้) Macrobenchmark จะแสดงข้อผิดพลาดแทนที่จะรายงานการวัดที่ไม่ถูกต้องหรือไม่สมบูรณ์ คุณ ระงับข้อผิดพลาดเหล่านี้ได้ด้วยอาร์กิวเมนต์ androidx.benchmark.suppressErrors

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

ปรับแต่งการเปรียบเทียบ

ฟังก์ชัน measureRepeated ยอมรับพารามิเตอร์ต่างๆ ที่มีผลต่อ เมตริกที่ไลบรารีรวบรวม วิธีเริ่มต้นและคอมไพล์แอป หรือจำนวน การทำซ้ำที่การเปรียบเทียบทำงาน

บันทึกเมตริก

เมตริกคือข้อมูลประเภทหลักที่ดึงมาจากการเปรียบเทียบ เมตริกที่พร้อมให้คุณใช้งานมีดังนี้

ดูข้อมูลเพิ่มเติมเกี่ยวกับเมตริกได้ที่บันทึกเมตริก Macrobenchmark

ปรับปรุงข้อมูลการติดตามด้วยเหตุการณ์ที่กำหนดเอง

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

CompilationMode

Macrobenchmark สามารถระบุ CompilationMode ซึ่งกำหนดว่าแอปต้องคอมไพล์ล่วงหน้าจากไบต์โค้ด DEX (รูปแบบไบต์โค้ดภายใน APK) เป็นโค้ดเครื่อง (คล้ายกับ C++ ที่คอมไพล์ล่วงหน้า) มากน้อยเพียงใด

โดยค่าเริ่มต้น Macrobenchmark จะทำงานด้วย CompilationMode.DEFAULT ซึ่งจะติดตั้ง Baseline Profile (หากมี) ใน Android 7 (API ระดับ 24) ขึ้นไป หากใช้ Android 6 (API ระดับ 23) หรือเก่ากว่า โหมดการคอมไพล์จะคอมไพล์ APK อย่างเต็มรูปแบบ เป็นลักษณะการทำงานเริ่มต้นของระบบ

คุณติดตั้ง Baseline Profile ได้หากแอปเป้าหมายมีทั้ง Baseline Profile และไลบรารี ProfileInstaller

ใน Android 7 ขึ้นไป คุณสามารถปรับแต่ง CompilationMode เพื่อส่งผลต่อ จำนวนการคอมไพล์ล่วงหน้าในอุปกรณ์เพื่อจำลองการคอมไพล์ล่วงหน้า (AOT) หรือการแคช JIT ในระดับต่างๆ ดู CompilationMode.Full, CompilationMode.Partial, CompilationMode.None และ CompilationMode.Ignore

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

StartupMode

หากต้องการเริ่มกิจกรรม คุณสามารถส่งโหมดเริ่มต้นที่กำหนดไว้ล่วงหน้าได้ ดังนี้ COLD, WARM หรือ HOT พารามิเตอร์นี้จะเปลี่ยนวิธีที่ กิจกรรมเปิดขึ้นและสถานะกระบวนการเมื่อเริ่มการทดสอบ

ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทการเริ่มต้นได้ที่เวลาที่ใช้ในการเริ่มต้นแอป

ตัวอย่าง

โปรเจ็กต์ตัวอย่างมีอยู่ใน Macrobenchmark Sample ของที่เก็บใน GitHub

แสดงความคิดเห็น

หากต้องการรายงานปัญหาหรือส่งคำขอฟีเจอร์สำหรับ Jetpack Macrobenchmark โปรดดูเครื่องมือติดตามปัญหาแบบสาธารณะ