বেসলাইন প্রোফাইল ডিবাগ করা

এই ডকুমেন্ট থেকে আপনি পেশাদার পদ্ধতি ও সমস্যার সমাধান করার ধাপ সম্পর্কে জানতে পারবেন, যার সাহায্যে সমস্যা শনাক্ত করতে পারবেন এবং আপনার বেসলাইন প্রোফাইল সঠিকভাবে কাজ করছে কিনা তা নিশ্চিত করতে পারবেন, যাতে আপনি সবচেয়ে বেশি সুবিধা পান।

বিল্ড সংক্রান্ত সমস্যা

আপনি যদি 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 in Android, বেসলাইন প্রোফাইল তৈরি করার জন্য Gradle-এর ম্যানেজ করা ডিভাইস ব্যবহার করে বলে এই সমস্যা হয়। ব্যর্থতা প্রত্যাশিত, কারণ সাধারণত আপনার এমুলেটরে পারফর্ম্যান্স বেঞ্চমার্ক চালানো উচিত নয়। তবে, বেসলাইন প্রোফাইল তৈরি করার সময় আপনি পারফর্ম্যান্স মেট্রিক সংগ্রহ করেন না বলে, সুবিধার জন্য এমুলেটরে বেসলাইন প্রোফাইল সংগ্রহ চালাতে পারেন। এমুলেটরের সাথে বেসলাইন প্রোফাইল ব্যবহার করতে, কমান্ড-লাইন থেকে বিল্ড ও ইনস্টলেশন সম্পূর্ণ করুন এবং বেসলাইন প্রোফাইল নিয়ম চালু করতে একটি আর্গুমেন্ট সেট করুন:

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

বিকল্প হিসেবে, আপনি Android Studio-তে কাস্টম রান কনফিগারেশন তৈরি করতে পারেন যাতে রান > কনফিগারেশন এডিট করুন বিকল্প বেছে নিয়ে এমুলেটরে বেসলাইন প্রোফাইল চালু করা যায়:

Now in Android-এ বেসলাইন প্রোফাইল তৈরি করতে কাস্টম রান কনফিগারেশন যোগ করা
ছবি ১. Now in Android-এ বেসলাইন প্রোফাইল তৈরি করতে কাস্টম রান কনফিগারেশন যোগ করুন।

প্রোফাইল ইনস্টলেশন ও অ্যাপ্লিকেশন যাচাই করুন

আপনি যে APK বা Android App Bundle (AAB) পরীক্ষা করছেন সেটি বেসলাইন প্রোফাইল সহ বিল্ড ভেরিয়েন্ট থেকে এসেছে কিনা তা চেক করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. Android Studio-তে, বিল্ড > APK বিশ্লেষণ করুন বিকল্প বেছে নিন।
  2. আপনার AAB বা APK খুলুন।
  3. baseline.prof ফাইলটি আছে কিনা তা কনফার্ম করুন:

    • আপনি যদি কোনও AAB পরীক্ষা করেন, তাহলে প্রোফাইলটি /BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof-এ আছে।
    • আপনি APK পরীক্ষা করলে, প্রোফাইলটি /assets/dexopt/baseline.prof-এ আছে।

      এই ফাইলটি থাকলে বোঝা যায় যে বিল্ড কনফিগারেশন সঠিকভাবে করা হয়েছে। এটি না থাকলে, এর অর্থ হল Android Runtime ইনস্টল করার সময় কোনও প্রি-কম্পাইলেশন নির্দেশাবলী পাবে না।

      Android Studio-তে APK Analyzer ব্যবহার করে বেসলাইন প্রোফাইল চেক করা
      ছবি ২. Android Studio-তে APK Analyzer ব্যবহার করে বেসলাইন প্রোফাইল চেক করুন।

অ্যাপ চলছে এমন ডিভাইসে বেসলাইন প্রোফাইল কম্পাইল করতে হবে। আপনি যখন Android Studio বা Gradle র‍্যাপার কমান্ড-লাইন টুল ব্যবহার করে ডিবাগ করা যায় না এমন বিল্ড ইনস্টল করেন, তখন ডিভাইসে কম্পাইলেশন অটোমেটিক হয়। আপনি যদি Google Play Store থেকে অ্যাপ ইনস্টল করেন, তাহলে বেসলাইন প্রোফাইলগুলি ইনস্টল করার সময় নয়, ব্যাকগ্রাউন্ড ডিভাইস আপডেটের সময় কম্পাইল করা হয়। অন্যান্য টুল ব্যবহার করে অ্যাপ ইনস্টল করা হলে, পরবর্তী ব্যাকগ্রাউন্ড DEX অপ্টিমাইজেশন প্রসেসের সময় কম্পাইলেশনের জন্য প্রোফাইল এনকিউ করার দায়িত্ব Jetpack ProfileInstaller লাইব্রেরির।

এইসব ক্ষেত্রে, আপনার বেসলাইন প্রোফাইল ব্যবহার করা হচ্ছে কিনা তা নিশ্চিত করতে চাইলে, আপনাকে হয়ত বেসলাইন প্রোফাইল কম্পাইল করতে বাধ্য করতে হবে। 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")
        }
    }
}

জাভা

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
অ্যাপ স্টোর বা প্যাকেজ ম্যানেজারের মাধ্যমে অ্যাপ ইনস্টল করার সময় এই অ্যাপের জন্য কোনও প্রোফাইল ইনস্টল করা হয়নি। এই সমস্যার কোডের প্রধান কারণ হল ProfileInstallerInitializer বন্ধ থাকার কারণে প্রোফাইল ইনস্টলার রান করেনি। মনে রাখবেন, এই সমস্যার কথা রিপোর্ট করার সময়, অ্যাপ্লিকেশন APK-তে এখনও একটি এম্বেড করা প্রোফাইল পাওয়া গেছে। এম্বেড করা প্রোফাইল খুঁজে না পাওয়া গেলে, যে ত্রুটি কোডটি ফেরত দেওয়া হয় সেটি হল RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED।
RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
APK বা AAB-তে একটি প্রোফাইল পাওয়া গেছে এবং কম্পাইল করার জন্য সারিবদ্ধ করা হয়েছে। ProfileInstaller-এর মাধ্যমে কোনও প্রোফাইল ইনস্টল করা হলে, সিস্টেমের মাধ্যমে পরবর্তী সময়ে ব্যাকগ্রাউন্ড DEX অপ্টিমাইজেশন চালানোর সময় কম্পাইলেশনের জন্য এটি সারিবদ্ধ করা হয়। কম্পাইলেশন সম্পূর্ণ না হওয়া পর্যন্ত প্রোফাইল অ্যাক্টিভ হয় না। কম্পাইলেশন সম্পূর্ণ না হওয়া পর্যন্ত আপনার বেসলাইন প্রোফাইল বেঞ্চমার্ক করার চেষ্টা করবেন না। আপনাকে হয়ত বেসলাইন প্রোফাইল জোর করে কম্পাইল করতে হবে। Android 9 (API 28) এবং তার পরবর্তী যেকোনও ভার্সনে চলা ডিভাইসে Play Store বা প্যাকেজ ম্যানেজার থেকে অ্যাপ ইনস্টল করা হলে এই সমস্যা হবে না, কারণ ইনস্টলেশনের সময় কম্পাইলেশন করা হয়।
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 লেভেল ২৮) এবং তার পরবর্তী ভার্সনে কাজ করে।
RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST
অ্যাপ প্যাকেজের জন্য PackageManager কোয়েরি করার সময় PackageManager.NameNotFoundException থ্রো করা হয়। এটি খুব কমই ঘটে। অ্যাপটি আনইনস্টল করে সবকিছু আবার ইনস্টল করে দেখুন।
RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ
আগের যাচাইকরণ ফলাফলের ক্যাশে ফাইল আছে, কিন্তু সেটি পড়া যাচ্ছে না। এটি খুব কমই হওয়া উচিত। অ্যাপটি আনইনস্টল করে সবকিছু আবার ইনস্টল করে দেখুন।

প্রোডাকশনে ProfileVerifier ব্যবহার করুন

প্রোডাকশনে, আপনি ProfileVerifier-এর সাথে অ্যানালিটিক্স-রিপোর্টিং লাইব্রেরি ব্যবহার করতে পারেন, যেমন Firebase-এর জন্য Google Analytics, যাতে প্রোফাইল স্ট্যাটাস নির্দেশ করে এমন অ্যানালিটিক্স ইভেন্ট তৈরি করা যায়। যেমন, এটি আপনাকে দ্রুত সতর্ক করে যদি কোনও নতুন অ্যাপ ভার্সন রিলিজ করা হয় যাতে বেসলাইন প্রোফাইল নেই।

বেসলাইন প্রোফাইল কম্পাইল করতে বাধ্য করা

আপনার বেসলাইন প্রোফাইলের কম্পাইলেশন স্ট্যাটাস 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 ব্যবহার করে কম্পাইলেশন ট্রিগার করা হয়েছে। এটি বেসলাইন প্রোফাইল হতে পারে অথবা অ্যাপ ব্যবহার করার সময় সংগ্রহ করা প্রোফাইল হতে পারে।

DEX এবং r8.json-এ স্টার্টআপ প্রোফাইল অ্যাপ্লিকেশন যাচাই করুন

আপনার DEX ফাইলের ক্লাস লেআউট অপ্টিমাইজ করার জন্য R8-এর মাধ্যমে বিল্ড টাইমে স্টার্টআপ প্রোফাইল নিয়ম ব্যবহার করা হয়। এই বিল্ড-টাইম অপ্টিমাইজেশন, বেসলাইন প্রোফাইল (baseline.prof) যেভাবে ব্যবহার করা হয় তার থেকে আলাদা, কারণ সেগুলি APK বা AAB-এর মধ্যে প্যাকেজ করা থাকে যাতে ART অন-ডিভাইস কম্পাইলেশন করতে পারে। যেহেতু বিল্ড প্রসেসের সময় স্টার্টআপ প্রোফাইল নিয়ম প্রয়োগ করা হয়, তাই আপনার APK বা AAB-এর মধ্যে আলাদা করে কোনও startup.prof ফাইল থাকে না যা আপনি পরীক্ষা করতে পারেন। পরিবর্তে, DEX ফাইল লেআউটে স্টার্টআপ প্রোফাইলের প্রভাব দেখা যায়।

r8.json-এর মাধ্যমে DEX অ্যারেঞ্জমেন্ট পরীক্ষা করুন (AGP 8.8 বা তার পরবর্তী ভার্সনের জন্য সাজেস্ট করা হয়)

Android Gradle Plugin (AGP) 8.8 বা তার পরবর্তী ভার্সন ব্যবহার করা প্রোজেক্টের ক্ষেত্রে, আপনি যাচাই করতে পারবেন যে জেনারেট করা r8.json ফাইলটি পরীক্ষা করে স্টার্টআপ প্রোফাইল প্রয়োগ করা হয়েছে কিনা। এই ফাইলটি আপনার AAB-এর মধ্যে প্যাকেজ করা আছে।

  1. আপনার AAB আর্কাইভ খুলুন এবং r8.json ফাইলটি খুঁজুন।
  2. dexFiles অ্যারের জন্য ফাইলটি সার্চ করুন, যা জেনারেট করা DEX ফাইলের তালিকা দেখায়।
  3. dexFiles অবজেক্ট খুঁজুন যাতে "startup": true কী-ভ্যালু পেয়ার আছে। এটি স্পষ্টভাবে ইঙ্গিত করে যে স্টার্টআপ প্রোফাইল নিয়ম সেই নির্দিষ্ট DEX ফাইলের লেআউট অপ্টিমাইজ করার জন্য প্রয়োগ করা হয়েছে।

    "dexFiles": [
     {
       "checksum": "...",
       "startup": true // This flag confirms profile application to this DEX file
     },
     // ... other DEX files
    ]
    

সব AGP ভার্সনের জন্য DEX অ্যারেঞ্জমেন্ট পরীক্ষা করুন

আপনি ৮.৮-এর থেকে কম AGP ভার্সন ব্যবহার করলে, আপনার স্টার্টআপ প্রোফাইল সঠিকভাবে প্রয়োগ করা হয়েছে কিনা তা যাচাই করার প্রাথমিক উপায় হল DEX ফাইল পরীক্ষা করা। আপনি AGP 8.8 বা তার পরবর্তী কোনও ভার্সন ব্যবহার করলে এবং ম্যানুয়ালি DEX লেআউট চেক করতে চাইলে, এই পদ্ধতি ব্যবহার করতে পারেন। যেমন, আপনি যদি প্রত্যাশিত পারফর্ম্যান্সের উন্নতি দেখতে না পান। DEX-এর ব্যবস্থা পরীক্ষা করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. Android Studio-তে বিল্ড > APK বিশ্লেষণ করুন বিকল্প ব্যবহার করে আপনার AAB বা APK খুলুন।
  2. প্রথম DEX ফাইলে নেভিগেট করুন। যেমন, classes.dex।
  3. এই DEX ফাইলের কন্টেন্ট পরীক্ষা করুন। আপনার স্টার্টআপ প্রোফাইল ফাইলে (startup-prof.txt) সংজ্ঞায়িত ক্রিটিক্যাল ক্লাস এবং পদ্ধতিগুলি এই প্রাথমিক DEX ফাইলে উপস্থিত আছে কিনা তা আপনি যাচাই করতে পারবেন। অ্যাপ্লিকেশন সফল হওয়ার অর্থ হল, দ্রুত লোড করার জন্য এইসব স্টার্টআপ-ক্রিটিক্যাল কম্পোনেন্টকে অগ্রাধিকার দেওয়া হয়।

পারফর্ম্যান্স সংক্রান্ত সমস্যা

এই বিভাগে বেসলাইন প্রোফাইল সঠিকভাবে নির্ধারণ ও বেঞ্চমার্ক করার কিছু পেশাদার পদ্ধতি দেখানো হয়েছে যাতে আপনি সেগুলি থেকে সবচেয়ে বেশি সুবিধা পেতে পারেন।

স্টার্টআপ মেট্রিক সঠিকভাবে বেঞ্চমার্ক করুন

আপনার স্টার্টআপ মেট্রিক্স সুনির্দিষ্ট হলে, আপনার বেসলাইন প্রোফাইল আরও কার্যকর হবে। দুটি মূল মেট্রিক হল প্রাথমিক ডিসপ্লেতে সময় (TTID) এবং সম্পূর্ণ ডিসপ্লেতে সময় (TTFD)।

অ্যাপ প্রথম ফ্রেম ড্র করলে TTID হয়। এটি যতটা সম্ভব ছোট রাখা গুরুত্বপূর্ণ কারণ কিছু দেখানোর অর্থ হল ব্যবহারকারীকে দেখানো যে অ্যাপটি চলছে। অ্যাপ যে রেসপন্সিভ তা দেখানোর জন্য আপনি অনির্দিষ্ট প্রোগ্রেস ইন্ডিকেটরও দেখাতে পারেন।

TTFD হল সেই সময় যখন অ্যাপের সাথে ইন্টার‍্যাক্ট করা যায়। ব্যবহারকারীর বিরক্তি এড়াতে এটি যতটা সম্ভব ছোট রাখা গুরুত্বপূর্ণ। আপনি যদি সঠিকভাবে TTFD সিগন্যাল করেন, তাহলে আপনি সিস্টেমকে বলছেন যে TTFD-এর পথে যে কোডটি চালানো হয়েছে সেটি অ্যাপ স্টার্টআপের অংশ। এর ফলে, সিস্টেম প্রোফাইলে এই কোডটি দেখানোর সম্ভাবনা বেশি।

আপনার অ্যাপ যাতে দ্রুত রেসপন্স করে তার জন্য TTID এবং TTFD যতটা সম্ভব কম রাখুন।

সিস্টেমটি TTID শনাক্ত করতে, Logcat-এ এটি দেখাতে এবং স্টার্টআপ বেঞ্চমার্কের অংশ হিসেবে এটি রিপোর্ট করতে পারে। তবে, সিস্টেম TTFD নির্ধারণ করতে পারে না এবং অ্যাপটি সম্পূর্ণভাবে আঁকা ইন্টারেক্টিভ অবস্থায় পৌঁছালে রিপোর্ট করার দায়িত্ব অ্যাপটির। আপনি reportFullyDrawn() কল করে এটি করতে পারেন অথবা Jetpack Compose ব্যবহার করলে ReportDrawn কল করে এটি করতে পারেন। অ্যাপটি সম্পূর্ণভাবে ড্র করা হয়েছে বলে বিবেচনা করার আগে যদি আপনার একাধিক ব্যাকগ্রাউন্ড টাস্ক থাকে যা সম্পূর্ণ করতে হবে, তাহলে আপনি FullyDrawnReporter ব্যবহার করতে পারেন, যেমনটি স্টার্টআপ টাইমিংয়ের নির্ভুলতা উন্নত করুন-এ বর্ণনা করা হয়েছে।

লাইব্রেরি প্রোফাইল এবং কাস্টম প্রোফাইল

প্রোফাইলের প্রভাব বেঞ্চমার্ক করার সময়, Jetpack লাইব্রেরির মতো লাইব্রেরি থেকে কন্ট্রিবিউট করা প্রোফাইল থেকে আপনার অ্যাপের প্রোফাইলের সুবিধা আলাদা করা কঠিন হতে পারে। আপনি APK তৈরি করার সময় Android Gradle প্লাগ-ইন লাইব্রেরি ডিপেন্ডেন্সিতে যেকোনও প্রোফাইল এবং আপনার কাস্টম প্রোফাইল যোগ করে। এটি সামগ্রিক পারফর্ম্যান্স অপ্টিমাইজ করার জন্য ভালো এবং আপনার রিলিজ বিল্ডের জন্য সাজেস্ট করা হয়। তবে, আপনার কাস্টম প্রোফাইল থেকে কতটা অতিরিক্ত পারফর্ম্যান্স পাওয়া গেছে তা পরিমাপ করা কঠিন হয়ে পড়ে।

আপনার কাস্টম প্রোফাইলের মাধ্যমে প্রদান করা অতিরিক্ত অপ্টিমাইজেশন ম্যানুয়ালি দেখার একটি দ্রুত উপায় হল, এটি সরিয়ে দেওয়া এবং আপনার বেঞ্চমার্ক রান করা। তারপর এটি পরিবর্তন করে আপনার বেঞ্চমার্ক আবার রান করুন। দুটির মধ্যে তুলনা করলে, আপনি শুধু লাইব্রেরি প্রোফাইল এবং লাইব্রেরি প্রোফাইলের সাথে আপনার কাস্টম প্রোফাইল ব্যবহার করে অপ্টিমাইজেশনের সুবিধা দেখতে পাবেন।

প্রোফাইল তুলনা করার একটি অটোমেটিক উপায় হল নতুন বিল্ড ভেরিয়েন্ট তৈরি করা যাতে শুধুমাত্র লাইব্রেরি প্রোফাইল থাকে, আপনার কাস্টম প্রোফাইল নয়। এই ভেরিয়েন্টের বেঞ্চমার্কের সাথে রিলিজ ভেরিয়েন্টের তুলনা করুন যাতে লাইব্রেরি প্রোফাইল ও আপনার কাস্টম প্রোফাইল, দুটিই আছে। নিম্নলিখিত উদাহরণ থেকে বোঝা যাবে যে কীভাবে শুধুমাত্র লাইব্রেরি প্রোফাইল অন্তর্ভুক্ত করে এমন ভেরিয়েন্ট সেট-আপ করতে হয়। আপনার প্রোফাইল কনজিউমার মডিউলে 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"))
    }
  }
}

আগের কোডের উদাহরণটি সব ভেরিয়েন্ট থেকে 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 কল ছাড়াই অ্যাপ স্টার্টআপ সাপোর্ট করে, এমনকি শুধুমাত্র স্টার্টআপ বেঞ্চমার্ক করার সময় ব্যবহার করার জন্য হলেও। এটি আপনার বেঞ্চমার্কের বিভিন্ন ইটারেশনের মধ্যে সম্ভাব্য সর্বনিম্ন পরিবর্তনশীলতা নিশ্চিত করতে সাহায্য করে।

আপনার অ্যাপ Hilt ব্যবহার করলে, Microbenchmark ও Hilt-এ বেঞ্চমার্কিং করার সময় আপনি ফেক I/O-বাউন্ড ইমপ্লিমেন্টেশন প্রদান করতে পারবেন।

ব্যবহারকারীর সব গুরুত্বপূর্ণ অভিজ্ঞতা কভার করা

আপনার বেসলাইন প্রোফাইল জেনারেশনে ব্যবহারকারীর সমস্ত গুরুত্বপূর্ণ অভিজ্ঞতা সঠিকভাবে কভার করা গুরুত্বপূর্ণ। বেসলাইন প্রোফাইল ব্যবহার করে, কভার করা হয়নি এমন কোনও ব্যবহারকারীর অভিজ্ঞতা উন্নত করা যাবে না। সবচেয়ে কার্যকর বেসলাইন প্রোফাইলে সব সাধারণ স্টার্টআপ ব্যবহারকারীর অভিজ্ঞতা এবং পারফর্ম্যান্স-সেনসিটিভ অ্যাপ-মধ্যস্থ ব্যবহারকারীর অভিজ্ঞতা যেমন স্ক্রলিং লিস্ট অন্তর্ভুক্ত থাকে।

A/B টেস্টিং কম্পাইল-টাইম প্রোফাইল পরিবর্তন

যেহেতু স্টার্ট-আপ ও বেসলাইন প্রোফাইল হল কম্পাইল-টাইম অপ্টিমাইজেশন, তাই প্রোডাকশন রিলিজের জন্য Google Play Store ব্যবহার করে সরাসরি বিভিন্ন APK-এর A/B টেস্টিং সাধারণত সমর্থিত নয়। প্রোডাকশনের মতো পরিবেশে প্রভাব মূল্যায়ন করতে, নিম্নলিখিত পদ্ধতিগুলি বিবেচনা করুন:

  • অফ-সাইকেল রিলিজ: আপনার ব্যবহারকারীর একটি ছোট শতাংশের জন্য অফ-সাইকেল রিলিজ আপলোড করুন যেখানে শুধুমাত্র প্রোফাইল পরিবর্তন অন্তর্ভুক্ত থাকে। এর ফলে আপনি পারফর্ম্যান্সের পার্থক্যের উপর বাস্তব-জগতের মেট্রিক সংগ্রহ করতে পারবেন।

  • লোকাল বেঞ্চমার্কিং: প্রোফাইল প্রয়োগ করে এবং না করে আপনার অ্যাপের লোকাল বেঞ্চমার্কিং করুন। তবে, মনে রাখবেন যে স্থানীয় বেঞ্চমার্কিং আপনাকে প্রোফাইলের জন্য সবচেয়ে ভালো পরিস্থিতি দেখায়, কারণ এতে ART থেকে ক্লাউড প্রোফাইল-এর প্রভাব অন্তর্ভুক্ত থাকে না যা প্রোডাকশন ডিভাইসে থাকে।