2.16

View in English

2.16 प्रदर्शन इंजीनियरिंग

अवलोकन और प्रेरणा

प्रदर्शन इंजीनियरिंग कोड को जानबूझकर, सहज ज्ञान के बजाय मापन का उपयोग करते हुए, पर्याप्त रूप से तेज़ बनाने की कला है। यह अध्याय कोड और कंपोनेंट के स्तर पर काम करता है: फ़ंक्शन, लूप, डेटा संरचनाएँ, क्वेरी, आवंटन (एलोकेशन), और जिस तरह कोई एक सेवा अपना समय व्यतीत करती है। यह अध्याय 3.5 का साथी है, जो सिस्टम स्तर पर प्रदर्शन को संभालता है (स्केलिंग आउट, लोड बैलेंसिंग, क्षमता और लचीलापन)। जब कोई सिस्टम धीमा होता है, तो अध्याय 3.5 पूछता है कि आपको कितनी मशीनों की आवश्यकता है; यह अध्याय पूछता है कि एक मशीन पहले स्थान पर इतना अधिक काम क्यों कर रही है। आपको आमतौर पर दोनों की आवश्यकता होगी, और कोड-स्तरीय दृष्टिकोण वह जगह है जहाँ लागत और लेटेंसी की एक आश्चर्यजनक मात्रा वास्तव में छिपी होती है।

बड़ी टीमों के लिए, यह अनुशासन महत्वपूर्ण है क्योंकि प्रदर्शन चुपचाप क्षीण होता है। कोई एक कमिट किसी सेवा को धीमा नहीं बनाता, लेकिन हज़ार छोटे कमिट, जिनमें से प्रत्येक एक डेटाबेस कॉल या एक असीमित लूप जोड़ता है, बनाते हैं। मापने, बजट बनाने और प्रदर्शन को गेट करने की एक साझा पद्धति के बिना, आप इस क्षरण की खोज तभी करते हैं जब कोई ग्राहक शिकायत करता है या कोई लॉन्च ध्वस्त हो जाता है। एक पद्धति प्रदर्शन को एक वीरतापूर्ण अग्निशमन कार्य से एक नियमित गुण में बदल देती है जिसकी आप रक्षा करते हैं।

उद्यमों के लिए, प्रदर्शन पैसा है: तेज़ कोड का अर्थ है कम मशीनें, कम क्लाउड बिल, और बिना अधिक प्रावधान (ओवर-प्रोविज़निंग) के लेटेंसी पर सर्विस-लेवल एग्रीमेंट (SLA) को पूरा करने की क्षमता। सरकार के लिए, प्रदर्शन पहुँच है: एक पेज जो कमज़ोर मोबाइल कनेक्शन पर पुराने फ़ोन पर लोड होता है, वह किसी नागरिक के लाभ दावे को पूरा करने और छोड़ देने के बीच का अंतर है। सार्वजनिक सिस्टम को पुनरुत्पादनीय बेंचमार्क साक्ष्य की भी आवश्यकता होती है, क्योंकि खरीद और निरीक्षण निकाय आपसे केवल दावा करने के बजाय संख्याओं को साबित करने के लिए कहेंगे।

मुख्य सिद्धांत

  • अनुकूलन (ऑप्टिमाइज़) करने से पहले मापें। बॉटलनेक लगभग कभी वहाँ नहीं होता जहाँ आप अनुमान लगाते हैं। प्रोफ़ाइल करें, फिर कार्य करें।
  • समय से पहले अनुकूलन से बचें। Donald Knuth की चेतावनी सही है: ऐसे कोड को अनुकूलित करना जो मायने नहीं रखता, स्पष्टता की कीमत चुकाता है और कुछ हासिल नहीं करता।
  • “पर्याप्त रूप से तेज़” को एक संख्या के रूप में परिभाषित करें। लक्ष्य और पर्सेंटाइल वाला एक प्रदर्शन बजट राय को पास या फ़ेल में बदल देता है।
  • औसत झूठ बोलते हैं; पर्सेंटाइल सच बताते हैं। टेल (p99) वह है जो उपयोगकर्ता महसूस करते हैं, न कि माध्य (मीन)।
  • एल्गोरिद्मिक जीत माइक्रो-ट्यूनिंग को मात देती है। एक बेहतर जटिलता वर्ग किसी भी मात्रा में कॉन्स्टेंट-फ़ैक्टर चतुराई को पीछे छोड़ देता है।
  • लेटेंसी और थ्रूपुट अलग-अलग लक्ष्य हैं। एक को सुधारना दूसरे को खराब कर सकता है; जानें कि आप किसके लिए भुगतान कर रहे हैं।
  • ईमानदारी से बेंचमार्क करें या बिल्कुल न करें। वार्म-अप, विचरण (वेरिएंस), और एक प्रतिनिधि वर्कलोड वास्तविक संख्याओं को कल्पना से अलग करते हैं।
  • CI में प्रदर्शन को गेट करें, प्रोडक्शन में इसे देखें। मर्ज से पहले पकड़ी गई रिग्रेशन सस्ती होती हैं; उपयोगकर्ताओं द्वारा पकड़ी गई महंगी।

अनुशंसाएँ

पहले मापें, और किसी भी लाइन को छूने से पहले प्रोफ़ाइल करें

इस क्षेत्र का सबसे पुराना नियम सबसे अधिक अनदेखा किया जाने वाला है: अनुकूलन से पहले बॉटलनेक खोजें। एक प्रोफ़ाइलर का उपयोग करें, एक टूल जो किसी चल रहे प्रोग्राम का नमूना लेता है या उसे इंस्ट्रूमेंट करता है ताकि यह दिखाया जा सके कि वह समय और मेमोरी कहाँ खर्च करता है। CPU को प्रोफ़ाइल करें (कौन से फ़ंक्शन चक्र जलाते हैं), मेमोरी और एलोकेशन को (क्या आवंटित किया जाता है और कितनी बार, क्योंकि एलोकेशन चर्न गार्बेज-कलेक्शन विराम को संचालित करता है), और I/O को (डिस्क, नेटवर्क या डेटाबेस पर प्रतीक्षा में बिताया गया समय)। एक फ़्लेम ग्राफ़, एक स्टैक्ड विज़ुअलाइज़ेशन जहाँ प्रत्येक बॉक्स एक फ़ंक्शन है और उसकी चौड़ाई बिताया गया समय है, प्रमुख लागत को एक नज़र में स्पष्ट कर देता है: सबसे चौड़े बॉक्स देखें, सबसे गहरे स्टैक नहीं। सबसे बड़ी लागत को पहले अनुकूलित करें, फिर से मापें, और जब आप बजट तक पहुँच जाएँ तो रुक जाएँ। यह अध्याय 9.2 की ऑब्ज़र्वेबिलिटी प्रथाओं से जुड़ता है, क्योंकि एक प्रोडक्शन प्रोफ़ाइल किसी लैपटॉप से किए गए किसी भी अनुमान से बेहतर होती है।

विपरीत त्रुटि से भी बचें। Knuth की पूरी पंक्ति यह है कि समय से पहले अनुकूलन कई बुराइयों की जड़ है, और उनका मतलब उन छोटी अक्षमताओं से था जो आपको काल्पनिक गति के लिए पठनीय कोड का त्याग करने के लिए ललचाती हैं। पहले स्पष्ट संस्करण लिखें, मापें, और केवल उस कोड को अनुकूलित करें जिसे प्रोफ़ाइलर दोषी ठहराता है।

प्रदर्शन बजट के साथ परिभाषित करें कि “पर्याप्त रूप से तेज़” का क्या अर्थ है

गति अमूर्त रूप में कोई गुण नहीं है; यह एक लक्ष्य है जिसे आप या तो पूरा करते हैं या चूक जाते हैं। एक प्रदर्शन बजट निर्धारित करें: एक ठोस सीमा जैसे “300 ms से कम p99 चेकआउट लेटेंसी” या “यह एंडपॉइंट प्रति अनुरोध 1 MB से कम आवंटित करता है।” इसे किसी ऐसी चीज़ से जोड़ें जो उपयोगकर्ता या व्यवसाय महसूस करते हैं, और इसे औसत के बजाय पर्सेंटाइल के रूप में व्यक्त करें, क्योंकि माध्य उस धीमी टेल को छिपा देता है जहाँ वास्तविक उपयोगकर्ता रहते हैं। यदि 1% अनुरोधों में 5 सेकंड लगते हैं, तो आपका औसत ठीक दिख सकता है जबकि ग्राहकों का एक महत्वपूर्ण हिस्सा परेशानी झेलता है। बजट किसी टीम को “पूर्ण” की एक साझा, निर्विवाद परिभाषा और एक रेखा देते हैं जिसे कोई रिग्रेशन दृश्य रूप से पार करता है।

माइक्रो-ऑप्टिमाइज़ेशन से पहले एल्गोरिद्मिक दक्षता की ओर बढ़ें

सबसे बड़ी, सबसे सस्ती जीत एल्गोरिद्मिक दक्षता से आती है, यानी इनपुट बढ़ने पर काम कैसे बढ़ता है, जिसे Big O नोटेशन (वृद्धि दर को वर्गीकृत करने का एक तरीका, जिससे एक O(n log n) सॉर्ट एक O(n squared) सॉर्ट की तुलना में कहीं बेहतर स्केल करता है) के साथ वर्णित किया जाता है। एक नेस्टेड लूप जो दस आइटम पर अदृश्य है, दस हज़ार पर एक आपदा बन जाता है। किसी हॉट फ़ंक्शन को हाथ से ट्यून करने से पहले, पूछें कि क्या यह मौलिक रूप से बहुत अधिक काम कर रहा है: एक आकस्मिक N+1 क्वेरी, एक रैखिक स्कैन जो एक हैश लुकअप होना चाहिए, या दोहराया गया काम जिसे मेमोआइज़ किया जा सकता है। यह अध्याय 2.13 में एल्गोरिद्मिक आधारों से जुड़ता है। कोई भी मात्रा में कॉन्स्टेंट-फ़ैक्टर ट्यूनिंग गलत जटिलता वर्ग को नहीं बचाती।

लेटेंसी को थ्रूपुट से अलग करें, और टेल का सम्मान करें

लेटेंसी यह है कि एक ऑपरेशन में कितना समय लगता है; थ्रूपुट यह है कि प्रति इकाई समय कितने ऑपरेशन पूरे होते हैं। ये एक ही लक्ष्य नहीं हैं, और एक को अनुकूलित करना दूसरे को नुकसान पहुँचा सकता है। बैचिंग थ्रूपुट में सुधार करती है लेकिन बैच के पहले आइटम में लेटेंसी जोड़ती है; समानांतर वर्कर जोड़ने से थ्रूपुट बढ़ता है लेकिन कंटेंशन के माध्यम से टेल लेटेंसी बिगड़ सकती है। तय करें कि आपके उपयोगकर्ताओं को वास्तव में किसकी आवश्यकता है। और हमेशा टेल पर नज़र रखें: p95 और p99 लेटेंसी, सबसे धीमे 5% और 1% अनुरोध, क्योंकि पैमाने पर कोई उपयोगकर्ता कई अनुरोध करता है और अक्सर टेल से टकराता है। पर्सेंटाइल की रिपोर्ट करें, उन पर अलर्ट करें, और उनके लिए बजट रखें।

समानांतरता (पैरेललिज़्म) की सीमाओं को जानें

जब आप समानांतरीकरण करते हैं, तो Amdahl के नियम को याद रखें: प्रोसेसर जोड़ने से मिलने वाला स्पीडअप उस काम के अंश द्वारा सीमित होता है जिसे क्रमिक रूप से चलना ही होता है। यदि किसी कार्य का 10% स्वाभाविक रूप से अनुक्रमिक है, तो कोई भी संख्या में कोर आपको 10x स्पीडअप से आगे नहीं ले जा सकते। कंकरेंसी (कार्य को इस तरह संरचित करना कि कार्य स्वतंत्र रूप से प्रगति कर सकें) और पैरेललिज़्म (वास्तव में उन्हें एक ही समय पर निष्पादित करना) वास्तविक जटिलता जोड़ते हैं, रेस कंडीशन से लेकर समन्वय ओवरहेड तक। यह मान लेने से पहले कि अधिक थ्रेड आपको बचाएँगे, अनुक्रमिक अंश मापें, और ईमानदार रहें कि सबसे सरल सही संस्करण अक्सर पर्याप्त रूप से तेज़ होता है।

कैशिंग और डेटा लोकैलिटी का उपयोग करें, और उनकी लागतों का सम्मान करें

एक कैश, हाल ही में या महंगे तरीके से गणना किए गए परिणामों का एक तेज़ भंडार, आपके पास उपलब्ध सबसे शक्तिशाली और सबसे खतरनाक प्रदर्शन उपकरण है। Phil Karlton की यह उक्ति कि कंप्यूटर विज्ञान की दो कठिन समस्याएँ कैश इनवैलिडेशन और चीज़ों का नामकरण हैं, एक चेतावनी है: एक स्टेल कैश गलत उत्तर देता है, और इनवैलिडेशन लॉजिक वह जगह है जहाँ सूक्ष्म बग पनपते हैं। जानबूझकर कैश करें, एक्सपायरी सेट करें, और हिट रेट को अनुकूलित करने से पहले अपनी सटीकता की कहानी जानें। सबसे निचले स्तर पर, रेफ़रेंस की लोकैलिटी, साथ में उपयोग किए गए डेटा को मेमोरी में एक-दूसरे के निकट रखना, CPU कैश पदानुक्रम का लाभ उठाती है और बिना किसी एल्गोरिद्मिक परिवर्तन के, कैश मिस को हिट में बदलकर कोड को कई गुना तेज़ बना सकती है। इसी कारण सन्निहित (कंटिगुअस) ऐरे पॉइंटर-चेज़िंग संरचनाओं को मात देते हैं। यह अध्याय 3.4 में डेटा लेआउट विकल्पों से मेल खाता है।

ईमानदारी से बेंचमार्क करें और माइक्रोबेंचमार्क पर अविश्वास करें

एक बेंचमार्क जो झूठ बोलता है, कोई बेंचमार्क न होने से भी बदतर है, क्योंकि यह झूठा आत्मविश्वास देता है। मापने से पहले वार्म अप करें, ताकि आप एक बार की स्टार्टअप और जस्ट-इन-टाइम कंपाइलेशन के बजाय स्थिर-स्थिति (स्टेडी-स्टेट) व्यवहार का समय लें। कई पुनरावृत्तियाँ चलाएँ और विचरण की रिपोर्ट करें, न कि एक अकेली भाग्यशाली संख्या। यथार्थवादी डेटा आकारों और वितरणों के साथ एक प्रतिनिधि वर्कलोड का उपयोग करें, क्योंकि किसी खिलौना इनपुट पर माइक्रोबेंचमार्क अक्सर कोड की वास्तविक गति के बजाय आपके टेस्ट को हटाने की कंपाइलर की क्षमता को मापता है। क्लासिक जालों से सावधान रहें: एक मान जिसे ऑप्टिमाइज़र अप्रयुक्त साबित करके हटा देता है, एक लूप जिसे रनटाइम बाहर उठा लेता है, या एक कैश जो बेंचमार्क में वार्म है और प्रोडक्शन में कोल्ड। संदेह होने पर, पूरे पथ को मापें, अलग किए गए फ़ंक्शन को नहीं।

CI में प्रदर्शन को गेट करें और प्रोडक्शन में इसे देखें

प्रदर्शन को एक ऐसा गुण बनाएँ जिसकी पाइपलाइन रक्षा करती है। अध्याय 2.4 की रणनीति में प्रदर्शन परीक्षण जोड़ें, रिग्रेशन गेट के साथ जो बिल्ड को फ़ेल करते हैं जब कोई प्रमुख बेंचमार्क या बजट किसी थ्रेशोल्ड से अधिक बिगड़ता है। यह धीमी वृद्धि को मर्ज होने से पहले पकड़ लेता है। फिर अध्याय 9.2 की टेलीमेट्री के साथ प्रोडक्शन में लूप को बंद करें: अपने बजट के विरुद्ध वास्तविक लेटेंसी पर्सेंटाइल, एलोकेशन दरों और धीमी क्वेरी को ट्रैक करें, क्योंकि प्रोडक्शन ट्रैफ़िक उन मामलों को खोजता है जिनकी आपके बेंचमार्क ने कभी कल्पना नहीं की।

ट्रेड-ऑफ़: फ़ायदे और नुकसान

दृष्टिकोणफ़ायदेनुकसान
सहज ज्ञान के आधार पर अभी अनुकूलित करेंउत्पादक महसूस होता है; कभी-कभार भाग्यशाली जीतआमतौर पर गलत कोड को ट्यून करता है; बिना किसी लाभ के जटिलता जोड़ता है
पहले मापें, फिर अनुकूलित करेंवास्तविक बॉटलनेक को लक्षित करता है; साक्ष्य-आधारितटूलिंग और अनुशासन की आवश्यकता; शुरू करने में धीमा
कैशिंगबड़ा लेटेंसी और थ्रूपुट लाभइनवैलिडेशन बग; स्टेल डेटा; मेमोरी लागत
अधिक समानांतरतासमानांतर कार्य पर उच्च थ्रूपुटAmdahl सीमा; कंटेंशन; कंकरेंसी बग
माइक्रो-ऑप्टिमाइज़ेशनकॉन्स्टेंट फ़ैक्टर को निचोड़ता हैछोटी सीमा; पठनीयता को नुकसान पहुँचाता है; अक्सर शोर
एल्गोरिद्मिक सुधारजीत इनपुट आकार के साथ स्केल होती हैविश्लेषण की आवश्यकता; कभी-कभी एक बड़ा पुनर्लेखन
CI प्रदर्शन गेटरिग्रेशन को जल्दी और सस्ते में रोकता हैअस्थिर (फ्लेकी) बेंचमार्क विश्वास को नष्ट करते हैं; स्थिर वातावरण की आवश्यकता

केंद्रीय तनाव प्रयास बनाम प्रतिफल का है, और समाधान मापन है। प्रदर्शन कार्य में तेज़ी से घटता प्रतिफल होता है: पहला प्रोफ़ाइल-निर्देशित फ़िक्स लेटेंसी को आधा कर सकता है, दसवाँ कोड जटिलता को दोगुना करते हुए एक प्रतिशत बचा सकता है। आप इसे बिना हाथ में संख्या और हिट करने के लिए बजट के अनुकूलन से इनकार करके हल करते हैं। उस फ़िक्स को खोजने के लिए मापें जो करने लायक है, और गति के लिए ही गति का पीछा करने के बजाय जिस क्षण आप बजट साफ़ कर लें, रुक जाएँ।

अपनी टीम के साथ चर्चा करने के लिए प्रश्न

  1. क्या आपके पास अपने महत्वपूर्ण पथों के लिए एक लिखित प्रदर्शन बजट है, और क्या इसे पर्सेंटाइल के रूप में व्यक्त किया गया है? कई टीमों में एक अस्पष्ट भावना होती है कि चीज़ें “तेज़” होनी चाहिए लेकिन कोई ऐसी संख्या नहीं जिसके विरुद्ध कोई फ़ेल हो सके, जिसका अर्थ है कि प्रदर्शन तब तक किसी का काम नहीं है जब तक वह टूट न जाए। “p99 300 ms से कम” जैसा एक बजट लक्ष्य को ठोस बनाता है, समीक्षकों को लागू करने के लिए कुछ देता है, और किसी रिग्रेशन को धीमी फिसलन के बजाय एक दृश्य घटना में बदल देता है। यह बड़ी टीमों पर सबसे अधिक मायने रखता है, जहाँ लेटेंसी कई हाथों से रेंगकर आती है और कोई एक लेखक संचित लागत नहीं देखता। अपना वर्तमान लेटेंसी डेटा लाएँ और पूछें कि क्या आप औसत की रिपोर्ट कर रहे हैं, जो आपकी चापलूसी करता है, या पर्सेंटाइल, जो सच बताते हैं। यदि आप यह नहीं बता सकते कि “पर्याप्त रूप से तेज़” का अर्थ एक संख्या के रूप में क्या है, तो यह ठीक करने वाली पहली चीज़ है।

  2. जब आपने आखिरी बार कुछ अनुकूलित किया, तो क्या किसी प्रोफ़ाइलर ने आपको बताया कि कहाँ देखना है, या आपने अनुमान लगाया? बॉटलनेक प्रसिद्ध रूप से कहीं और होता है, जहाँ अनुभवी इंजीनियर अपेक्षा करते हैं, और गलत कोड को ट्यून करने में बिताया गया समय दो बार खोया हुआ समय है, एक बार काम में और एक बार जोड़ी गई जटिलता में। एक ऐसी संस्कृति जो पहले प्रोफ़ाइल करती है, अपना प्रयास वहाँ खर्च करती है जहाँ वह फल देता है और स्पष्ट कोड को अकेला छोड़ देती है। अपनी टीम से पिछले तीन प्रदर्शन फ़िक्स को याद करने के लिए कहें और क्या प्रत्येक किसी मापन से शुरू हुआ या किसी अनुमान से। विचार करें कि क्या आप प्रोडक्शन में, या एक यथार्थवादी स्टेजिंग वातावरण में प्रोफ़ाइल कर सकते हैं, क्योंकि लैपटॉप प्रोफ़ाइल बुरी तरह गुमराह कर सकती है। उत्तर बताता है कि क्या आपका प्रदर्शन कार्य इंजीनियरिंग है या लोककथा।

  3. आज किसी प्रदर्शन रिग्रेशन को प्रोडक्शन तक पहुँचने से क्या रोकता है? बढ़ती हुई टीम पर, ईमानदार उत्तर अक्सर “एक ग्राहक शिकायत” होता है, जिसका अर्थ है कि उपयोगकर्ता आपका रिग्रेशन टेस्ट हैं। एक CI गेट जो बिल्ड को फ़ेल करता है जब कोई बेंचमार्क या बजट बिगड़ता है, समस्या को तब पकड़ लेता है जब उसे ठीक करना सस्ता होता है और लेखक को अभी भी परिवर्तन याद होता है। चर्चा करें कि क्या आपके बेंचमार्क गेट करने के लिए पर्याप्त स्थिर हैं, क्योंकि एक अस्थिर प्रदर्शन परीक्षण जो झूठा अलार्म देता है, उसे नज़रअंदाज़ या अक्षम कर दिया जाएगा। इस बारे में भी बात करें कि आप प्रोडक्शन में क्या देखते हैं, क्योंकि कुछ रिग्रेशन केवल वास्तविक ट्रैफ़िक और डेटा के तहत दिखाई देते हैं। लक्ष्य प्रदर्शन को एक ऐसा गुण बनाना है जिसकी सिस्टम स्वचालित रूप से रक्षा करता है, न कि वह जिसे आप किसी घटना में फिर से खोजते हैं।

  4. क्या आप प्रत्येक महत्वपूर्ण पथ पर लेटेंसी या थ्रूपुट के लिए अनुकूलन करते हैं, और क्या किसी ने वह विकल्प लिखा है? ये अलग-अलग लक्ष्य हैं जो विपरीत दिशाओं में खींचते हैं: बैचिंग और समानांतर वर्कर थ्रूपुट बढ़ाते हैं लेकिन व्यक्तिगत अनुरोधों में लेटेंसी जोड़ सकते हैं, इसलिए सहज ज्ञान से अनुकूलन करने वाली टीम अक्सर गलत अक्ष खरीदती है और उपयोगकर्ताओं को मशीन समय बचाने के लिए प्रतीक्षा कराती है जिसकी किसी को कमी नहीं थी। एक बड़ी टीम पर खतरा बढ़ जाता है, क्योंकि एक समूह किसी साझा सेवा को बल्क थ्रूपुट के लिए ट्यून करता है जबकि दूसरा इंटरैक्टिव लेटेंसी के लिए उस पर निर्भर करता है, और न तो एक-दूसरे का लक्ष्य जानता है। प्रत्येक पथ का वास्तविक उपयोग पैटर्न (इंटरैक्टिव अनुरोध बनाम बैकग्राउंड बैच), वर्तमान पर्सेंटाइल लेटेंसी, और आपको जिस निरंतर थ्रूपुट की आवश्यकता है, उसे लाएँ, फिर किसी डिफ़ॉल्ट को उभरने देने के बजाय स्पष्ट रूप से अक्ष तय करें। किसी SLA के तहत किसी उद्यम या सरकारी सिस्टम के लिए, नाम बताएँ कि समझौता किस मेट्रिक के विरुद्ध लिखा गया है, क्योंकि अनमापी गई धुरी को अनुकूलित करना अनुबंध का उल्लंघन कर सकता है जबकि आपके डैशबोर्ड स्वस्थ दिखते हैं।

  5. आप कैसे जानते हैं कि आपके बेंचमार्क वास्तविक काम को मापते हैं न कि ऑप्टिमाइज़र आपके टेस्ट को हटा रहा है? एक बेंचमार्क जो झूठ बोलता है, कोई बेंचमार्क न होने से भी बदतर है, क्योंकि यह टीम को झूठा आत्मविश्वास देता है और फिर भी एक रिग्रेशन शिप हो जाता है। टीमें नियमित रूप से एक खिलौना इनपुट पर एक कोल्ड रन से एकल भाग्यशाली संख्या की रिपोर्ट करती हैं, जो उपयोगकर्ताओं द्वारा वास्तव में सामना किए जाने वाले व्यवहार के बजाय स्टार्टअप, जस्ट-इन-टाइम कंपाइलेशन, और अप्रयुक्त कोड को हटाने की कंपाइलर की क्षमता को मापती है। एक उदाहरण बेंचमार्क लाएँ और उससे पूछताछ करें: क्या यह वार्म अप करता है, कई पुनरावृत्तियाँ चलाता है, विचरण की रिपोर्ट करता है, प्रतिनिधि डेटा आकार और वितरण का उपयोग करता है, और अपने परिणाम पर डेड-कोड एलिमिनेशन को हराता है। प्रतिस्पर्धी खिंचाव यह है कि ईमानदार बेंचमार्क त्वरित माइक्रोबेंचमार्क की तुलना में लिखने और चलाने में धीमे होते हैं, इसलिए सहमत हों कि सस्ते अनुमान कहाँ स्वीकार्य हैं और कहाँ आप कठोरता की माँग करते हैं। किसी सार्वजनिक या विनियमित सेटिंग में जहाँ खरीद और निरीक्षण निकाय आपसे संख्याओं को पुनरुत्पादित करने के लिए कहेंगे, परिणाम के साथ डिवाइस, वर्कलोड और वातावरण को कैप्चर करें ताकि दावे को केवल दावा करने के बजाय सत्यापित किया जा सके।

  6. जब प्रदर्शन कार्य उन्हीं इंजीनियरों के लिए सुविधाओं के साथ प्रतिस्पर्धा करता है, तो आप कैसे निर्णय लेते हैं, और बजट प्राधिकरण किसके पास है? प्रदर्शन में तेज़ी से घटता प्रतिफल होता है, इसलिए पहला प्रोफ़ाइल-निर्देशित फ़िक्स लेटेंसी को आधा कर सकता है जबकि दसवाँ दोगुनी कोड जटिलता के लिए एक प्रतिशत बचाता है, और बिना किसी नियम के सबसे तेज़ आवाज़ या निकटतम समय सीमा जीतती है। प्रतिस्पर्धी विचार वास्तविक हैं: अनसुलझा प्रदर्शन ऋण चुपचाप बढ़ता है और उसे बाद में जोड़ना अधिक महंगा होता जाता है, फिर भी बजट से परे गति का पीछा करना रोडमैप को भूखा रखता है और जटिलता जोड़ता है जो भविष्य के काम को धीमा करती है। प्रत्येक महत्वपूर्ण पथ के लिए वर्तमान बजट स्थिति, मशीनों या खोए हुए रूपांतरण में यथास्थिति की अनुमानित लागत, और अगले अनुकूलन का सीमांत प्रतिफल लाएँ, ताकि ट्रेड-ऑफ़ दबाव के बजाय साक्ष्य पर किया जाए। किसी बड़े उद्यम या सरकारी कार्यक्रम के लिए, नाम बताएँ कि प्रदर्शन बजट का स्वामी कौन है और इसके विरुद्ध इंजीनियरिंग समय खर्च करने को कौन अधिकृत कर सकता है, क्योंकि एक ऐसा लक्ष्य जिसकी रक्षा करने के लिए कोई जवाबदेह नहीं है, वह चुपचाप क्षीण हो जाता है।

क्षेत्र लेंस

स्टार्टअप। डिलीवरी की गति प्रक्रिया को मात देती है, इसलिए पुनर्लेखन और भव्य प्रदर्शन फ्रेमवर्क से बचें। उस पथ पर एक दोपहर एक प्रोफ़ाइलर के साथ बिताएँ जिसकी उपयोगकर्ता वास्तव में शिकायत करते हैं, सबसे बड़ी लागत को ठीक करें (अक्सर एक N+1 क्वेरी या एक आकस्मिक रैखिक स्कैन), और CI में एक हल्का पर्सेंटाइल बजट जोड़ें ताकि जीत चुपचाप रिग्रेस न हो सके। गहन अनुकूलन को उस क्षण के लिए सुरक्षित रखें जब कोई वास्तविक संख्या, न कि कोई अनुमान, कहे कि कोड बहुत धीमा है।

छोटा व्यवसाय। बिना किसी प्रदर्शन विशेषज्ञ और सीमित बजट के, उन टूल पर भरोसा करें जिनके लिए आप पहले से भुगतान करते हैं: आपके रनटाइम में प्रोफ़ाइलर, आपके होस्टिंग डैशबोर्ड में लेटेंसी पर्सेंटाइल, और आपके डेटाबेस में बिल्ट-इन क्वेरी एनालाइज़र। किसी ऐसी चीज़ से जुड़े एक या दो सादे बजट निर्धारित करें जिसे ग्राहक महसूस करते हैं, जैसे पेज-लोड या चेकआउट समय, और उल्लंघन को ऐसा प्रोजेक्ट शुरू करने के बजाय एक तेज़ टियर खरीदने या सबसे खराब क्वेरी ठीक करने का संकेत मानें जिसे आप स्टाफ़ नहीं कर सकते।

उद्यम (एंटरप्राइज़)। फ़्लीट स्केल पर, प्रदर्शन प्रत्यक्ष लागत है, इसलिए इसे एक साझा अनुशासन के रूप में शासित करें: मानक प्रोफ़ाइलिंग टूल, व्यावसायिक मेट्रिक्स से जुड़े पर्सेंटाइल बजट, और लगातार लागू किए गए CI रिग्रेशन गेट ताकि किसी एक टीम की धीमी वृद्धि पूरे क्लाउड बिल को न बढ़ा दे। सेवाओं में बेसलाइन के विरुद्ध लेटेंसी, एलोकेशन और थ्रूपुट को ट्रैक करें, और पुनरुत्पादनीय बेंचमार्क साक्ष्य रखें, क्योंकि एक बड़े फ़्लीट पर 30% CPU कमी एक आवर्ती बचत है जो ऑडिट करने और SLA दंड से बचाव करने लायक है।

सरकार। प्रदर्शन एक पहुँच गारंटी है: एक पेज जो कमज़ोर कनेक्शन पर पुराने फ़ोन पर लोड होता है, यह तय करता है कि कोई नागरिक लाभ दावा पूरा करता है या नहीं। यथार्थवादी निम्न-स्तरीय उपकरणों और थ्रॉटल नेटवर्क के विरुद्ध स्पष्ट बजट निर्धारित करें, और पुनरुत्पादनीय बेंचमार्क परिणाम प्रकाशित करें जो डिवाइस, नेटवर्क और वर्कलोड को कैप्चर करते हैं, ताकि खरीद और निरीक्षण निकाय संख्याओं को विश्वास पर लेने के बजाय सत्यापित कर सकें। विक्रेता के दावों की तुलना में पारदर्शी, ऑडिट योग्य मापन को प्राथमिकता दें, और आपूर्तिकर्ताओं को उसी पुनरुत्पादनीय साक्ष्य के लिए जवाबदेह ठहराएँ।

उदाहरण

स्टार्टअप। एक छोटी SaaS टीम नोटिस करती है कि उनका डैशबोर्ड सुस्त महसूस होता है और इसे तेज़ फ्रेमवर्क में फिर से लिखने का लालच होता है। इसके बजाय वे एक प्रोफ़ाइलर और एक फ़्लेम ग्राफ़ के साथ एक दोपहर बिताते हैं, जो दिखाता है कि अनुरोध समय का 70% एक एकल एंडपॉइंट है जो प्रति पंक्ति एक डेटाबेस क्वेरी जारी करता है, क्लासिक N+1 पैटर्न। वे इसे एक बैच की गई क्वेरी से बदल देते हैं, लेटेंसी 1.2 सेकंड से घटकर 90 मिलीसेकंड हो जाती है, और वे एक हल्के CI बेंचमार्क में 200 ms का p99 बजट जोड़ते हैं ताकि फ़िक्स चुपचाप रिग्रेस न हो सके। कोई पुनर्लेखन नहीं, एक दोपहर, दस गुना जीत।

उद्यम (एंटरप्राइज़)। एक रिटेल प्लेटफ़ॉर्म हज़ारों इंस्टेंस चलाता है, और इसके क्लाउड बिल पर एक सिफ़ारिश सेवा का दबदबा है। एक प्रोफ़ाइलिंग अभियान भारी एलोकेशन चर्न पाता है जो बार-बार गार्बेज-कलेक्शन विराम का कारण बनता है, साथ ही एक कैश जिसकी हिट रेट खराब है। लोकैलिटी के लिए डेटा संरचनाओं को ट्यून करना और कैश कुंजियों को ठीक करना प्रति अनुरोध CPU को 40% कम कर देता है, जो टीम को उसी ट्रैफ़िक को 40% कम मशीनों पर चलाने देता है। यह बचत हफ़्तों में इंजीनियरिंग प्रयास के लिए भुगतान करती है, और एक p99 लेटेंसी SLA जिसका कभी-कभी उल्लंघन होता था, अब आराम से बना रहता है, संविदात्मक दंड से बचते हुए।

सरकार। एक राष्ट्रीय कर प्राधिकरण को पुराने उपकरणों और धीमे ग्रामीण कनेक्शनों पर नागरिकों की सेवा करनी चाहिए। टीम एक स्पष्ट बजट निर्धारित करती है: फ़ाइलिंग पेज को थ्रॉटल 3G प्रोफ़ाइल पर एक निम्न-स्तरीय फ़ोन पर 3 सेकंड से कम में इंटरैक्टिव हो जाना चाहिए। वे पेज को प्रोफ़ाइल करते हैं, इंटरैक्टिव-ब्लॉकिंग काम को कम करते हैं, और पुनरुत्पादनीय बेंचमार्क परिणाम प्रकाशित करते हैं, डिवाइस, नेटवर्क और वर्कलोड को कैप्चर करते हुए, ताकि निरीक्षण निकाय और एक्सेसिबिलिटी ऑडिटर दावे को विश्वास पर लेने के बजाय सत्यापित कर सकें। यहाँ प्रदर्शन कोई लागत लीवर नहीं बल्कि एक पहुँच गारंटी है जो सेवा को सभी के लिए उपयोग योग्य बनाए रखती है।

व्यावसायिक मामला: प्रेरणाएँ, ROI, और TCO

प्रदर्शन इंजीनियरिंग पर प्रतिफल तीन खातों में दिखाई देता है। पहला इन्फ्रास्ट्रक्चर लागत है: तेज़ कोड कम मशीनों पर वही काम करता है, और एक बड़े फ़्लीट के लिए 30% CPU कमी एक प्रत्यक्ष, आवर्ती बचत है जो एकमुश्त इंजीनियरिंग प्रयास को बौना बना देती है। दूसरा राजस्व और संतुष्टि है: लेटेंसी रूपांतरण, परित्याग और उपयोगकर्ता विश्वास से सहसंबंधित है, इसलिए टेल को कम करना केवल एक स्वच्छता कार्य नहीं बल्कि एक वृद्धि लीवर है। तीसरा टाला गया जोखिम है: एक SLA उल्लंघन दंड लाता है, और लोड के तहत ध्वस्त होने वाला लॉन्च प्रतिष्ठा को नुकसान और अग्निशमन लागत लाता है।

स्वामित्व की कुल लागत मामूली और अग्रिम-भारित है। आप प्रोफ़ाइलिंग टूल, एक स्थिर बेंचमार्किंग वातावरण, और CI गेट में निवेश करते हैं, साथ ही बजट लिखने और प्रोफ़ाइल पढ़ने का अनुशासन। बड़ी, छिपी हुई लागत विकल्प है: प्रदर्शन ऋण चुपचाप बढ़ता है, और लॉन्च के बाद किसी धीमे सिस्टम में गति को वापस जोड़ना इसे लगातार सुरक्षित रखने से कहीं अधिक महंगा है। नेतृत्व से उनकी अपनी इकाइयों में मामला बनाएँ। लेटेंसी को रूपांतरण या नागरिक पूर्णता दरों में अनुवादित करें, CPU को मासिक क्लाउड खर्च में अनुवादित करें, और एक रिग्रेशन गेट को टाली गई घटनाओं में अनुवादित करें। सबसे मजबूत तर्क यह है कि प्रदर्शन को कमिट दर कमिट सुरक्षित रखना सस्ता है और सड़ जाने के बाद उसे पुनर्प्राप्त करना विनाशकारी है।

एंटी-पैटर्न और नुकसान

  • बिना प्रोफ़ाइलिंग के अनुकूलन करना। ऐसे कोड को ट्यून करना जो बॉटलनेक नहीं है जबकि वास्तविक लागत अछूती रह जाती है।
  • समय से पहले अनुकूलन। काल्पनिक गति के लिए स्पष्टता का त्याग करना जिसे प्रोफ़ाइलर ने कभी चिह्नित नहीं किया होता।
  • औसत की रिपोर्टिंग। एक आरामदायक माध्य के पीछे एक दर्दनाक टेल को छिपाना; उपयोगकर्ता p99 महसूस करते हैं, औसत नहीं।
  • माइक्रोबेंचमार्क थिएटर। एक खिलौना वर्कलोड से संख्याएँ जिसे ऑप्टिमाइज़र ने आधा हटा दिया, बिना किसी वार्म-अप या विचरण रिपोर्ट के।
  • बिना इनवैलिडेशन कहानी के कैश। स्टेल या गलत डेटा परोसते हुए हिट रेट का पीछा करना।
  • यह मानना कि अधिक थ्रेड मदद करते हैं। Amdahl के नियम और अनुक्रमिक अंश को अनदेखा करना, फिर कंटेंशन में डूब जाना।
  • कोई रिग्रेशन गेट नहीं। उपयोगकर्ताओं को प्रदर्शन परीक्षण बनने देना क्योंकि CI में कुछ भी बजट की रक्षा नहीं करता।
  • गलत अक्ष का अनुकूलन। बैचिंग के साथ थ्रूपुट खरीदना जब उपयोगकर्ताओं को कम लेटेंसी की आवश्यकता थी, या इसका उल्टा।

परिपक्वता मॉडल

  • स्तर 1, आरंभ करें (Initiate): प्रदर्शन को तभी संबोधित किया जाता है जब कुछ टूटता है। कोई बजट नहीं, कोई प्रोफ़ाइलिंग आदत नहीं, कोई बेंचमार्क नहीं। अनुकूलन सहज ज्ञान से प्रेरित अनुमान है, और औसत ही एकमात्र मेट्रिक है जिसकी कोई रिपोर्ट करता है।
  • स्तर 2, विकसित करें (Develop): कुछ टीमें घटनाओं के दौरान प्रोफ़ाइल करती हैं और कुछ बेंचमार्क रखती हैं, लेकिन यह प्रथा असंगत है और व्यक्तिगत उत्साह पर निर्भर करती है। एक या दो महत्वपूर्ण पथों के लिए बजट अनौपचारिक रूप से मौजूद हैं, और पर्सेंटाइल कुछ डैशबोर्ड पर दिखाई देते हैं, फिर भी शिप होने से पहले कुछ भी किसी रिग्रेशन को गेट नहीं करता और प्रत्येक टीम अपना खुद का दृष्टिकोण फिर से बनाती है।
  • स्तर 3, मानकीकृत करें (Standardize): महत्वपूर्ण पथ लिखित पर्सेंटाइल बजट रखते हैं, और प्रोफ़ाइलिंग किसी के भी अनुकूलन करने से पहले का दस्तावेज़ीकृत, अपेक्षित पहला कदम है। CI में रिग्रेशन गेट के साथ प्रदर्शन परीक्षण शामिल हैं, ईमानदार बेंचमार्किंग नियम (वार्म-अप, विचरण, प्रतिनिधि डेटा) लिखे और पूरे संगठन में लागू किए जाते हैं, और हर टीम अपने खुद के तरीके के बजाय एक ही पद्धति का पालन करती है।
  • स्तर 4, प्रबंधित करें (Manage): संगठन प्रदर्शन को एक नियंत्रित गुण के रूप में मापता है। लेटेंसी पर्सेंटाइल, थ्रूपुट, एलोकेशन दरें, और धीमी-क्वेरी गिनती को प्रोडक्शन और CI में स्पष्ट बेसलाइन के विरुद्ध ट्रैक किया जाता है, रिग्रेशन को बहस करने के बजाय थ्रेशोल्ड के विरुद्ध मात्रात्मक किया जाता है, और बजट रूपांतरण या क्लाउड खर्च जैसे व्यावसायिक मेट्रिक्स से जुड़े होते हैं ताकि कोई उल्लंघन डेटा-समर्थित निर्णय को ट्रिगर करे। बेंचमार्क साक्ष्य पुनरुत्पादनीय है और ऑडिट के लिए इसके डिवाइस, वर्कलोड और वातावरण के साथ कैप्चर किया जाता है।
  • स्तर 5, संचालित करें (Orchestrate): प्रदर्शन को लगातार सुधारा जाता है और पूरे संगठन में एकीकृत किया जाता है। बजट, प्रोफ़ाइलिंग, ईमानदार बेंचमार्किंग, और फ़्लेम-ग्राफ़ विश्लेषण नियमित कौशल हैं, रिग्रेशन गेट स्थिर और विश्वसनीय हैं, और प्रोडक्शन तथा CI डेटा स्वचालित रूप से लूप बंद करते हैं। संगठन ट्रैफ़िक, हार्डवेयर, और व्यावसायिक प्राथमिकताओं के बदलने पर बजट को अनुकूलित करता है, उन पथों की ओर प्रयास को फिर से संतुलित करता है जहाँ प्रतिफल सबसे अधिक है, और प्रदर्शन की रक्षा एक आवधिक अभियान के बजाय एक स्थायी गुण के रूप में करता है।

चर्चा के लिए विचार

  1. आपके किस महत्वपूर्ण पथ में आज एक लिखित, पर्सेंटाइल-आधारित बजट है, और कौन से केवल आशा से सुरक्षित हैं?
  2. किसी प्रोफ़ाइलर ने आपको आखिरी बार कब आश्चर्यचकित किया, और इसने आपको इस बारे में क्या सिखाया कि आप कहाँ मान लेते हैं कि समय जाता है?
  3. क्या आपके बेंचमार्क वार्म अप करते हैं, विचरण की रिपोर्ट करते हैं, और प्रतिनिधि डेटा का उपयोग करते हैं, या वे ऑप्टिमाइज़र को माप रहे हैं?
  4. आप ऐसे कोड को छिपाने के लिए मशीनों पर कहाँ खर्च कर रहे हैं जिसे एक प्रोफ़ाइलिंग अभियान सस्ता बना सकता है?
  5. आपके सबसे अधिक समानांतरीकृत वर्कलोड के लिए, अनुक्रमिक अंश क्या है, और क्या Amdahl का नियम उस स्पीडअप को सीमित करता है जिसका आप पीछा कर रहे हैं?
  6. यदि किसी टीम साथी ने एक परिवर्तन मर्ज किया जिसने p99 लेटेंसी को दोगुना कर दिया, तो किसी को नोटिस करने में कितना समय लगेगा, और उन्हें इसका पता कैसे चलेगा?

मुख्य निष्कर्ष

  • अनुकूलन करने से पहले मापें; बॉटलनेक शायद ही कभी वहाँ होता है जहाँ आप अनुमान लगाते हैं, और समय से पहले अनुकूलन बिना किसी लाभ के स्पष्टता की कीमत चुकाता है।
  • “पर्याप्त रूप से तेज़” को एक पर्सेंटाइल बजट के रूप में परिभाषित करें, क्योंकि औसत उस टेल को छिपा देते हैं जहाँ वास्तविक उपयोगकर्ता रहते हैं।
  • माइक्रो-ट्यूनिंग की तुलना में एल्गोरिद्मिक जीत (एक बेहतर Big O वर्ग) को प्राथमिकता दें, और जानें कि आपको लेटेंसी चाहिए या थ्रूपुट।
  • समानांतरता की सीमाओं (Amdahl का नियम) और कैशिंग के खतरों (इनवैलिडेशन और स्टेलनेस) का सम्मान करें।
  • वार्म-अप, विचरण, और प्रतिनिधि वर्कलोड के साथ ईमानदारी से बेंचमार्क करें, और माइक्रोबेंचमार्क पर अविश्वास करें।
  • CI में प्रदर्शन को गेट करें (अध्याय 2.4) और प्रोडक्शन में इसे देखें (अध्याय 9.2); अध्याय 3.5 में सिस्टम-स्तरीय दृष्टिकोण का पूरक बनें।
  • प्रदर्शन उद्यमों के लिए लागत है, सरकारों के लिए पहुँच है, और लगातार सुरक्षित रखना सस्ता लेकिन बाद में जोड़ना महंगा है।

संदर्भ और आगे पढ़ने के लिए

  • Brendan Gregg, Systems Performance: Enterprise and the Cloud (प्रोफ़ाइलिंग, फ़्लेम ग्राफ़, और पद्धति)।
  • Brendan Gregg, BPF Performance Tools (Linux पर व्यावहारिक ऑब्ज़र्वेबिलिटी और प्रोफ़ाइलिंग)।
  • Donald E. Knuth, “Structured Programming with go to Statements” (ACM Computing Surveys, 1974): समय-से-पहले-अनुकूलन कहावत का स्रोत।
  • Donald E. Knuth, The Art of Computer Programming (एल्गोरिद्मिक विश्लेषण और जटिलता)।
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms (Big O और एल्गोरिद्मिक दक्षता)।
  • Gene M. Amdahl, “Validity of the Single Processor Approach to Achieving Large-Scale Computing Capabilities” (1967): Amdahl के नियम की उत्पत्ति।
  • Ulrich Drepper, “What Every Programmer Should Know About Memory” (मेमोरी पदानुक्रम और डेटा लोकैलिटी)।
  • Martin Kleppmann, Designing Data-Intensive Applications (सिस्टम में लेटेंसी, थ्रूपुट, और टेल व्यवहार)।
  • Aleksey Shipilev, “JMH and the pitfalls of microbenchmarking” (मैनेज्ड रनटाइम पर ईमानदार बेंचमार्किंग प्रथा)।
  • Ilya Grigorik, High Performance Browser Networking (कम-बैंडविड्थ उपयोगकर्ताओं के लिए क्लाइंट-साइड और नेटवर्क प्रदर्शन)।