प्रोफ़ाइल जीपीयू रेंडरिंग टूल से पता चलता है कि रेंडरिंग पाइपलाइन के हर चरण को पिछले फ़्रेम को रेंडर करने में कितना समय लगा. इस जानकारी से, आपको पाइपलाइन में आने वाली समस्याओं का पता लगाने में मदद मिल सकती है. इससे, ऐप्लिकेशन की रेंडरिंग परफ़ॉर्मेंस को बेहतर बनाने के लिए ऑप्टिमाइज़ किया जा सकता है.
इस पेज पर, हर पाइपलाइन स्टेज के दौरान होने वाली प्रोसेस के बारे में कम शब्दों में बताया गया है. साथ ही, उन समस्याओं के बारे में बताया गया है जिनकी वजह से रुकावटें आ सकती हैं. इस पेज को पढ़ने से पहले, आपको प्रोफ़ाइल जीपीयू रेंडरिंग की स्पीड में दी गई जानकारी के बारे में पता होना चाहिए. इसके अलावा, यह समझने के लिए कि सभी चरण एक साथ कैसे काम करते हैं, रेंडरिंग पाइपलाइन के काम करने का तरीका देखें.
विज़ुअल के तौर पर जानकारी दिखाना
प्रोफ़ाइल जीपीयू रेंडरिंग टूल, अलग-अलग चरणों और उनके समय को ग्राफ़ के तौर पर दिखाता है. यह ग्राफ़, कलर-कोडेड हिस्टोग्राम के तौर पर होता है. पहली इमेज में, इस तरह के डिसप्ले का उदाहरण दिखाया गया है.
प्रोफ़ाइल जीपीयू रेंडरिंग ग्राफ़ में दिखाए गए हर वर्टिकल बार का हर सेगमेंट, पाइपलाइन के एक चरण को दिखाता है. इसे बार ग्राफ़ में किसी खास रंग का इस्तेमाल करके हाइलाइट किया जाता है. दूसरी इमेज में, हर रंग का मतलब बताया गया है.
हर रंग का मतलब समझने के बाद, अपने ऐप्लिकेशन के कुछ पहलुओं को टारगेट किया जा सकता है. इससे, रेंडरिंग की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने में मदद मिलती है.
स्टेज और उनके मतलब
इस सेक्शन में, हर चरण के दौरान होने वाली गतिविधियों के बारे में बताया गया है. साथ ही, इसमें उन वजहों के बारे में भी बताया गया है जिनकी वजह से बॉटलनेक आ सकता है.
इनपुट हैंडलिंग
पाइपलाइन की इनपुट हैंडलिंग स्टेज से यह पता चलता है कि ऐप्लिकेशन ने इनपुट इवेंट को हैंडल करने में कितना समय लगाया. इस मेट्रिक से पता चलता है कि ऐप्लिकेशन ने इनपुट इवेंट कॉलबैक के नतीजे के तौर पर कोड को कितनी देर तक एक्ज़ीक्यूट किया.
जब यह सेगमेंट बड़ा हो
इस सेक्शन में ज़्यादा वैल्यू आम तौर पर, इनपुट-हैंडलर इवेंट कॉलबैक के अंदर बहुत ज़्यादा काम या बहुत मुश्किल काम होने की वजह से होती है. ये कॉलबैक हमेशा मुख्य थ्रेड पर होते हैं. इसलिए, इस समस्या को हल करने के लिए, काम को सीधे तौर पर ऑप्टिमाइज़ करने या काम को किसी दूसरी थ्रेड पर ट्रांसफ़र करने पर फ़ोकस किया जाता है.
इस फ़ेज़ में, LazyColumn या LazyRow को स्क्रोल करते हुए भी दिखाया जा सकता है. जब उपयोगकर्ता का टच, स्क्रोल करने की ज़रूरी शर्तें पूरी करता है, तब लेज़ी लिस्ट, टच इवेंट का इस्तेमाल करके आइटम को डाइनैमिक तरीके से कंपोज़ और ले आउट करती है. अगर आपका ऐप्लिकेशन, स्क्रोल की पोज़िशन में बदलाव होने पर कस्टम काम करता है, तो इस ऑपरेशन को जल्द से जल्द पूरा करना ज़रूरी है, ताकि फ़्रेम ड्रॉप न हों. Android Studio में मौजूद सीपीयू प्रोफ़ाइलर या Perfetto जैसे प्रोफ़ाइलिंग टूल, इस समस्या के बारे में ज़्यादा जानकारी पाने में आपकी मदद कर सकते हैं. ज़्यादा जानकारी के लिए, सिस्टम ट्रेसिंग की खास जानकारी देखें.
ऐनिमेशन
ऐनिमेशन फ़ेज़ से पता चलता है कि उस फ़्रेम में चल रहे सभी ऐनिमेशन की स्थितियों का आकलन करने में कितना समय लगा. Compose में कुछ सामान्य ऐनिमेशन एपीआई ये हैं:
animate*AsState,
Transition,
और Animatable.
इसके अलावा, इस फ़ेज़ के दौरान Recomposer चलता है, ताकि स्नैपशॉट की स्थिति में हुए बदलावों को प्रोसेस किया जा सके और कंपोज़िशन को अपडेट किया जा सके. इसका मतलब है कि रीकंपोज़िशन का ओवरहेड अक्सर ऐनिमेशन स्टेज में सीधे तौर पर दिखता है.
Jetpack Compose यूज़र इंटरफ़ेस (यूआई) के लिए, Compose Runtime Tracing लाइब्रेरी शामिल करें. इससे आपको सिस्टम इवेंट के साथ-साथ कंपोज़िशन के बारे में ज़्यादा जानकारी मिल पाएगी.
जब यह सेगमेंट बड़ा हो
आम तौर पर, इस सेक्शन में ज़्यादा वैल्यू इसलिए दिखती हैं, क्योंकि ऐनिमेशन की वजह से स्टेट में बदलाव होता है. उदाहरण के लिए, फ़्लिंग ऐनिमेशन. यह आपके LazyColumn
या LazyRow को स्क्रोल करता है. इससे सूची में शामिल नए आइटम तेज़ी से कंपोज़ होते हैं, मेज़र किए जाते हैं, और असाइन किए जाते हैं.
दूरी मापें
स्क्रीन पर कंपोज़ेबल बनाने के लिए, Android आपके यूज़र इंटरफ़ेस (यूआई) ट्री में मौजूद लेआउट नोड पर तीन चरणों को पूरा करता है.
सबसे पहले, सिस्टम लेआउट नोड को मेज़र करता है. हर कंपोज़ेबल में कुछ खास बाधाएं और मॉडिफ़ायर होते हैं. इनसे स्क्रीन पर ऑब्जेक्ट के साइज़ की सीमाओं के बारे में पता चलता है. कुछ कंपोज़ेबल का साइज़ तय होता है. वहीं, कुछ कंपोज़ेबल का साइज़, पैरंट लेआउट कंटेनर से मिले कंस्ट्रेंट के हिसाब से बदलता रहता है.
इसके बाद, सिस्टम लेआउट नोड को जगह देता है. मेज़रमेंट फ़ेज़ के दौरान, Compose चाइल्ड नोड के साइज़ का हिसाब लगाता है. इसके बाद, वह प्लेसमेंट फ़ेज़ में आगे बढ़ता है. इस फ़ेज़ में, वह स्क्रीन पर लेआउट नोड के साइज़ और पोज़िशन तय करता है.
सिस्टम, बेहतर परफ़ॉर्मेंस के लिए हमेशा सिंगल-पास लेआउट का इस्तेमाल करता है. जब कंपोज़ेबल लेआउट अमान्य हो जाता है, तो Compose उस नोड का मेज़रमेंट करता है. साथ ही, लेआउट अपडेट को सिर्फ़ पैरंट हैरारकी तक पहुंचाता है. ऐसा तब होता है, जब चाइल्ड नोड का साइज़ या कंस्ट्रेंट बदलता है.
जब यह सेगमेंट बड़ा हो
इस सेक्शन में बड़ा सेगमेंट होने का मतलब है कि ऐप्लिकेशन, लेआउट फ़ेज़ में बहुत ज़्यादा समय बिता रहा है. इसमें लेआउट नोड की पोज़िशन तय करना और उसका साइज़ तय करना शामिल है. इन कार्रवाइयों में, कंपोज़ेबल के लिए मेज़रमेंट और प्लेसमेंट मॉडिफ़ायर को लागू करना शामिल है. अगर लेआउट ट्री बहुत ज़्यादा जटिल है, तो इससे फ़्रेम तैयार होने में देरी हो सकती है. इन मामलों में, परफ़ॉर्मेंस को बेहतर बनाने के लिए, अपने Compose ऐप्लिकेशन की परफ़ॉर्मेंस की तुलना अन्य ऐप्लिकेशन से करें. साथ ही, परफ़ॉर्मेंस के सबसे सही तरीके अपनाएं.
लेआउट पास की जांच करने और परफ़ॉर्मेंस से जुड़ी समस्याओं का पता लगाने के लिए, Android Studio में सीपीयू प्रोफ़ाइलर या Perfetto का इस्तेमाल करें. ज़्यादा जानकारी के लिए, सिस्टम ट्रेसिंग की खास जानकारी देखें.
जगह बदलना
ड्रॉ स्टेज, रेंडरिंग ऑपरेशनों को नेटिव ड्रॉइंग कमांड के क्रम में बदलता है. जैसे, बैकग्राउंड, शेप या टेक्स्ट को ड्रॉ करना. सिस्टम, इन निर्देशों को जीपीयू के ज़रिए लागू करने के लिए, डिसप्ले लिस्ट में सेव करता है.
ड्रॉ बार से पता चलता है कि डिसप्ले लिस्ट में कमांड कैप्चर करने में कितना समय लगता है. यह समय, उन सभी लेआउट नोड के लिए होता है जिन्हें इस फ़्रेम के लिए स्क्रीन पर अपडेट करना होता है. मेज़र किया गया समय, कस्टम ड्रॉइंग लॉजिक पर भी लागू होता है. यह लॉजिक, ड्रॉ मॉडिफ़ायर या कैनवस कंपोज़ेबल में हो सकता है.
जब यह सेगमेंट बड़ा हो
आसान शब्दों में कहें, तो इस मेट्रिक से यह पता चलता है कि अमान्य लेआउट नोड के लिए, सभी ड्रॉइंग कमांड को चलाने में कितना समय लगा.
इस मेज़रमेंट में, चाइल्ड नोड और वेक्टर ड्रॉएबल को ये कमांड भेजने में लगने वाला समय शामिल होता है. इस वजह से, जब आपको इस बार में अचानक बढ़ोतरी दिखे, तो इसकी वजह यह हो सकती है कि कई कंपोज़ेबल अचानक अमान्य हो गए हों. अमान्य होने पर, ड्रॉइंग के निर्देशों को फिर से लागू करना और लेआउट नोड की डिसप्ले लिस्ट को फिर से जनरेट करना ज़रूरी हो जाता है. इसके अलावा, ऐसा भी हो सकता है कि कुछ कस्टम कंपोज़ेबल या कैनवस में DrawScope को लागू करने के लिए, बहुत जटिल लॉजिक का इस्तेमाल किया गया हो.
इसके अलावा, Compose अक्सर अपने इंटरनल मेज़र और लेआउट पास को उस समय हैंडल करता है जिसे प्लैटफ़ॉर्म, ड्रॉ फ़ेज़ मानता है. इसलिए, सिर्फ़ ड्रॉइंग कमांड की वजह से नहीं, बल्कि महंगे या बहुत ज़्यादा इंटरनल मेज़र/लेआउट ऑपरेशन की वजह से भी ड्रॉ बार बढ़ सकता है. अगर आपको किसी तरह का शक़ हो, तो Perfetto ट्रेस कैप्चर करें. इससे आपको यह पता चलेगा कि ओवरहेड, ड्रॉइंग रूटीन या कंपोज़ मेज़र और लेआउट पास की वजह से हो रहा है या नहीं.
अपलोड करें
अपलोड मेट्रिक से पता चलता है कि मौजूदा फ़्रेम के दौरान, सीपीयू मेमोरी से जीपीयू मेमोरी में बिटमैप ऑब्जेक्ट ट्रांसफ़र करने में कितना समय लगता है.
सीपीयू और जीपीयू अलग-अलग प्रोसेसर होते हैं. इसलिए, इनके पास प्रोसेसिंग के लिए अलग-अलग रैम एरिया होते हैं. Android पर बिटमैप ड्रॉ करने पर, सिस्टम बिटमैप को जीपीयू मेमोरी में ट्रांसफ़र करता है. इसके बाद, जीपीयू उसे स्क्रीन पर रेंडर कर पाता है. इसके बाद, जीपीयू बिट मैप को कैश मेमोरी में सेव कर लेता है, ताकि सिस्टम को डेटा को फिर से ट्रांसफ़र न करना पड़े. ऐसा तब तक होता है, जब तक कि बनावट को जीपीयू बनावट कैश मेमोरी से हटा न दिया जाए.
ध्यान दें: Lollipop डिवाइसों पर, यह स्टेज बैंगनी रंग की होती है.
जब यह सेगमेंट बड़ा हो
किसी फ़्रेम के सभी संसाधनों को GPU मेमोरी में मौजूद होना चाहिए, ताकि उनका इस्तेमाल फ़्रेम बनाने के लिए किया जा सके. इसका मतलब है कि इस मेट्रिक की ज़्यादा वैल्यू का मतलब यह हो सकता है कि बहुत सारे छोटे संसाधन लोड हुए हैं या बहुत कम संसाधन लोड हुए हैं. आम तौर पर, ऐसा तब होता है, जब कोई ऐप्लिकेशन स्क्रीन के साइज़ के आस-पास का एक बिटमैप दिखाता है. एक और स्थिति तब होती है, जब कोई ऐप्लिकेशन बड़ी संख्या में थंबनेल दिखाता है.
इस बार को छोटा करने के लिए, इन तकनीकों का इस्तेमाल किया जा सकता है:
- यह पक्का करें कि आपके बिटमैप रिज़ॉल्यूशन, उस साइज़ से ज़्यादा बड़े न हों जिस पर उन्हें दिखाया जाएगा. उदाहरण के लिए, 1024x1024 इमेज को 48x48 इमेज के तौर पर न दिखाएं.
- अगले सिंक फ़ेज़ से पहले, एसिंक्रोनस तरीके से बिटमैप को पहले से अपलोड करने के लिए, Coil जैसी आधुनिक लाइब्रेरी का इस्तेमाल करना.
निर्देश जारी करना
समस्या वाले कमांड सेगमेंट से पता चलता है कि स्क्रीन पर डिसप्ले लिस्ट बनाने के लिए ज़रूरी सभी कमांड को पूरा होने में कितना समय लगता है.
सिस्टम, स्क्रीन पर डिसप्ले लिस्ट दिखाने के लिए, जीपीयू को ज़रूरी निर्देश भेजता है. आम तौर पर, यह कार्रवाई OpenGL ES एपीआई के ज़रिए की जाती है.
इस प्रोसेस में कुछ समय लगता है, क्योंकि सिस्टम हर कमांड के लिए फ़ाइनल ट्रांसफ़ॉर्मेशन और क्लिपिंग करता है. इसके बाद ही, कमांड को GPU को भेजा जाता है. इसके बाद, जीपीयू पर अतिरिक्त ओवरहेड होता है, जो फ़ाइनल कमांड की गिनती करता है. इन कमांड में फ़ाइनल ट्रांसफ़ॉर्मेशन और अतिरिक्त क्लिपिंग शामिल हैं.
जब यह सेगमेंट बड़ा हो
इस स्टेज में लगने वाला समय, सीधे तौर पर इस बात पर निर्भर करता है कि सिस्टम, दिए गए फ़्रेम में कितनी डिसप्ले लिस्ट रेंडर करता है और वे कितनी जटिल हैं. उदाहरण के लिए, कई ड्रॉ ऑपरेशन करने से, इस समय में बढ़ोतरी हो सकती है. खास तौर पर, उन मामलों में जहां हर ड्रॉ प्रिमिटिव की लागत कम होती है. उदाहरण के लिए:
for (i in 0 until 1000) { canvas.drawPoint() }
को जारी करने में ज़्यादा खर्च आता है. इसकी तुलना में:
canvas.drawPoints(thousandPointArray)
कमांड जारी करने और डिसप्ले लिस्ट को असल में ड्रॉ करने के बीच, हमेशा 1:1 का कोरिलेशन नहीं होता. समस्या की जानकारी देने वाली कमांड बार के उलट, ड्रॉ मेट्रिक से यह पता चलता है कि डिसप्ले लिस्ट में जारी की गई कमांड को कैप्चर करने में कितना समय लगा. समस्या की जानकारी देने वाली कमांड बार से यह पता चलता है कि जीपीयू को ड्रॉइंग कमांड भेजने में कितना समय लगा.
यह अंतर इसलिए दिखता है, क्योंकि सिस्टम, डिसप्ले सूचियों को जहां भी हो सके वहां कैश मेमोरी में सेव करता है. इस वजह से, कुछ मामलों में स्क्रोल, ट्रांसफ़ॉर्म या ऐनिमेशन के लिए, सिस्टम को डिसप्ले लिस्ट फिर से भेजनी पड़ती है. हालांकि, इसे फिर से बनाने की ज़रूरत नहीं होती. इसके लिए, ड्रॉइंग कमांड को शुरू से फिर से कैप्चर करना होता है. इस वजह से, आपको ड्रॉ कमांड का ज़्यादा बार नहीं, बल्कि समस्या कमांड का ज़्यादा बार इस्तेमाल किया गया बार दिख सकता है.
बफ़र स्वैप करना
जब Android, डिसप्ले लिस्ट को GPU को सबमिट कर देता है, तो सिस्टम एक फ़ाइनल कमांड जारी करता है. इससे ग्राफ़िक्स ड्राइवर को पता चलता है कि मौजूदा फ़्रेम का काम पूरा हो गया है. इस समय, ड्राइवर स्क्रीन पर अपडेट की गई इमेज दिखा सकता है.
जब यह सेगमेंट बड़ा हो
यह समझना ज़रूरी है कि जीपीयू, सीपीयू के साथ-साथ काम करता है. Android सिस्टम, जीपीयू को ड्रॉ कमांड जारी करता है. इसके बाद, अगले टास्क पर चला जाता है. जीपीयू, ड्रॉ करने की उन कमांड को एक कतार से पढ़ता है और उन्हें प्रोसेस करता है.
जब सीपीयू, जीपीयू के मुकाबले ज़्यादा तेज़ी से कमांड भेजता है, तो प्रोसेसर के बीच कम्यूनिकेशन की कतार पूरी हो सकती है. ऐसा होने पर, सीपीयू ब्लॉक हो जाता है और तब तक इंतज़ार करता है, जब तक अगली कमांड को रखने के लिए कतार में जगह नहीं बन जाती. यह फ़ुल-क्यू की स्थिति अक्सर स्वैप बफ़र के दौरान होती है. ऐसा इसलिए होता है, क्योंकि उस समय पूरे फ़्रेम के लिए कमांड सबमिट की जाती हैं.
इस समस्या को कम करने के लिए, जीपीयू पर होने वाले काम को कम करना ज़रूरी है. ऐसा ही आपको इश्यू कमांड फ़ेज़ के लिए करना होगा.
अन्य चीज़ें
रेंडरिंग सिस्टम को अपना काम पूरा करने में जितना समय लगता है उसके अलावा, मुख्य थ्रेड पर एक और काम होता है. इसका रेंडरिंग से कोई लेना-देना नहीं होता. इस काम में लगने वाले समय को अन्य समय के तौर पर रिपोर्ट किया जाता है. अन्य समय आम तौर पर, रेंडरिंग के दो लगातार फ़्रेम के बीच यूज़र इंटरफ़ेस (यूआई) थ्रेड पर होने वाले काम को दिखाता है.
जब यह सेगमेंट बड़ा हो
अगर यह वैल्यू ज़्यादा है, तो ऐसा हो सकता है कि आपके ऐप्लिकेशन में कॉल बैक, इंटेंट या अन्य काम हों जो किसी दूसरे थ्रेड पर होने चाहिए. Android Studio में सीपीयू प्रोफ़ाइलर या Perfetto जैसे टूल की मदद से, मुख्य थ्रेड पर चल रहे टास्क देखे जा सकते हैं. इस जानकारी से, आपको परफ़ॉर्मेंस को बेहतर बनाने के लिए टारगेट करने में मदद मिल सकती है. ज़्यादा जानकारी के लिए, सिस्टम ट्रेसिंग की खास जानकारी देखें.