2 पॉइंट द्वारा GN⁺ 2025-08-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • बिग O नोटेशन फ़ंक्शन के प्रदर्शन को इनपुट आकार बदलने पर उसकी वृद्धि के पैटर्न के रूप में व्यक्त करता है
  • लेख में उदाहरणों के साथ मुख्य रूप से constant, logarithmic, linear, और quadratic प्रकार के बिग O को समझाया गया है
  • डेटा संरचना और एल्गोरिदम के अनुसार time complexity अलग होती है, और array sorting, search आदि में इसका अंतर दिखता है
  • वास्तविक कोड प्रदर्शन सुधारने के लिए उपयुक्त data structure चुनना और loop के भीतर अनावश्यक operations हटाना सबसे महत्वपूर्ण है
  • बिग O हमेशा इनपुट और execution time के संबंध को सबसे सरल रूप में दिखाता है, और performance सुधारते समय कोड को सीधे मापना महत्वपूर्ण है

बिग O नोटेशन का अवलोकन

  • बिग O नोटेशन समय को सीधे मापने के बजाय इनपुट आकार (n) के अनुसार execution time की वृद्धि के पैटर्न को समझाने का तरीका है
  • यह फ़ंक्शन के execution time को input size के आधार पर वर्गीकृत करता है, और आम तौर पर constant (O(1)), logarithmic (O(log n)), linear (O(n)), और quadratic (O(n²)) रूप विश्लेषण के मुख्य विषय होते हैं
  • यह लेख शुरुआती पाठकों के लिए भी समझने योग्य तरीके से हर प्रकार की अवधारणा, visual उदाहरण और वास्तविक code examples के माध्यम से समझाता है

Iterating और linear algorithm

  • sum(n) फ़ंक्शन 1 से n तक जोड़ने वाली iteration संरचना का उदाहरण है, और input value n बढ़ने पर execution time भी सीधे अनुपात में बढ़ता है
  • वास्तव में sum(1e9) में लगभग 1 सेकंड, और sum(2e9) में लगभग 2 सेकंड लगते हैं, इसलिए wall-clock time O(n) पैटर्न में बढ़ता है
  • Time complexity फ़ंक्शन के input और execution time के बीच संबंध है, और इसे बिग O नोटेशन से व्यक्त किया जाता है (O(n) — n के अनुपात में)
  • iteration के बजाय गणितीय सूत्र sum(n) = (n*(n+1))/2 का उपयोग करने पर execution time input value n से स्वतंत्र, स्थिर (constant) रहता है
  • ऐसे फ़ंक्शन को constant time complexity O(1) कहा जाता है, जिसकी विशेषता यह है कि input बदलने पर execution time नहीं बढ़ता

बिग O नोटेशन की syntax

  • बिग O में O का अर्थ “Order (वृद्धि का क्रम)” से आता है, और यह सिर्फ वृद्धि के रूप को दर्शाता है
  • यह वास्तविक execution time का absolute value नहीं, बल्कि इनपुट के मुकाबले वृद्धि के 'pattern' को संक्षेप में दिखाता है
  • उदाहरण के लिए, O(n) फ़ंक्शन को 'O(2n)' या 'O(n+1)' जैसे जटिल रूप में नहीं लिखते, बल्कि सबसे सरल पद को ही चुना जाता है

इनपुट संरचना का उपयोग कर समय कम करना

  • sum(n) सूत्र वाले उदाहरण की तरह एल्गोरिदम सुधारकर time complexity को O(n) से O(1) में बदला जा सकता है
  • हालांकि, constant time complexity होने का मतलब यह नहीं कि वह हमेशा तेज़ ही होगा; किस प्रकार का operation है, इससे कुल execution time बदल सकता है
  • कोई O(n) algorithm कुछ विशेष inputs पर O(1) से तेज़ हो सकता है, लेकिन input size बढ़ने पर अंततः O(1) तरीका ही बेहतर साबित होता है

Sorting और quadratic algorithm: Bubble Sort उदाहरण

  • Bubble Sort पास-पास के numbers की अदला-बदली दोहराते हुए array को sort करने का एक बुनियादी उदाहरण है
  • अगर array पहले से sorted हो तो 1 pass में काम हो सकता है (O(n)), लेकिन reverse order में होने पर n बार तक traversal चाहिए → worst case में कुल operations n²
  • O(n²) algorithm में input बढ़ने के साथ execution time वर्गीय रूप में बहुत तेज़ी से बढ़ता है
  • वास्तविक उपयोग में बिग O हमेशा worst-case के आधार पर लिया जाता है (हालाँकि कुछ मामलों में average/best case भी लिखा जाता है)
  • array की शुरुआती स्थिति के अनुसार loop की संख्या कम हो सकती है, लेकिन worst case को देखते हुए इसे quadratic time complexity में ही रखा जाता है

Searching और logarithmic algorithm: Binary Search उदाहरण

  • Binary Search sorted range के मध्य मान का अनुमान लगाता है, और हर चरण में candidate range को आधा कर देता है
  • उदाहरण के लिए, 1~100 के बीच किसी संख्या को खोजने में अधिकतम 7 बार, और 1~1 अरब तक में भी 31 से कम प्रयासों में काम हो सकता है
  • हर चरण में candidate list आधी हो जाती है, इसलिए execution time O(log n) (logarithmic time complexity) होता है
  • logarithmic algorithm में n बढ़ने पर भी वृद्धि बहुत धीमी होती है (linear या quadratic की तुलना में कहीं अधिक efficient)
  • ग्राफ़ की तुलना में log n, n, n² के बीच वृद्धि का अंतर बहुत स्पष्ट दिखाई देता है

वास्तविक उपयोग: time complexity सुधारने के टिप्स

लिस्ट में item खोजना

  • सामान्य रूप से array में कोई value खोजने वाला फ़ंक्शन O(n) होता है
  • यदि बार-बार search करना हो, तो Set जैसी data structure का उपयोग करके इसे O(1) तक सुधारा जा सकता है
  • लेकिन new Set(array) में बदलने की प्रक्रिया स्वयं O(n) होती है, इसलिए यह केवल बार-बार lookup होने पर ही उपयुक्त है (conversion cost को ध्यान में रखते हुए)
  • उदाहरण: items.has("banana") constant time complexity देता है

index का उपयोग करके loop लिखना

  • नीचे की तरह loop के अंदर .indexOf का उपयोग करने वाला code अक्सर performance issue की वजह बनता है

    function buildList(items) {
      const output = [];
      for (const item of items) {
        const index = items.indexOf(item);
        output.push(`Item ${index + 1}: ${item}`);
      }
      return output.join("\n");
    }
    
  • .indexOf loop के अंदर O(n) operation है, इसलिए पूरा code मिलकर O(n^2) पैटर्न बन जाता है

  • index-based iteration या forEach((item, index) => ...) का उपयोग करने पर इसे O(n) तक सुधारा जा सकता है

    function buildList(items) {
      const output = [];
      for (let i = 0; i < items.length; i++) {
        output.push(`Item ${i + 1}: ${items[i]}`);
      }
      return output.join("\n");
    }
    

Memoization का उपयोग

  • factorial जैसे मामलों में, जहाँ repeated calls के दौरान duplicate calculation होती है, वहाँ result caching (Map का उपयोग) लागू करके performance सुधारी जा सकती है

  • Map में lookup O(1) होता है, इसलिए अनावश्यक recalculation कम हो जाती है

  • हालांकि caching मुख्य रूप से average time सुधारती है, और worst-case time complexity बदले बिना भी प्रदर्शन को प्रभावी रूप से बेहतर बना सकती है

    const cache = new Map();
    function factorial(n) {
      if (cache.has(n)) {
        return cache.get(n);
      }
      if (n === 0) {
        return 1;
      }
      const result = n * factorial(n - 1);
      cache.set(n, result);
      return result;
    }
    

प्रदर्शन मूल्यांकन और निष्कर्ष

  • कोड performance सुधारते समय सैद्धांतिक time complexity के साथ-साथ सीधे execution test करके वास्तविक सुधार की पुष्टि करनी चाहिए
  • बिग O इनपुट और execution time के संबंध और growth pattern को सबसे मूलभूत रूप में सरल बनाकर व्यक्त करता है
  • सही algorithm चुनकर और data structure को optimize करके code efficiency को अधिकतम किया जा सकता है

संक्षिप्त सार

  • बिग O नोटेशन फ़ंक्शन के input value और execution time के संबंध को व्यक्त करता है
  • मुख्य performance श्रेणियाँ: O(1) (constant), O(log n) (logarithmic), O(n) (linear), O(n^2) (quadratic)
  • efficient code लिखने के लिए उपयुक्त algorithm और loop optimization महत्वपूर्ण हैं
  • वास्तविक performance को सीधे मापकर सुधार की पुष्टि करना ज़रूरी है
  • growth pattern comparison graph की मदद से time complexity की विशेषताओं को एक नज़र में समझा जा सकता है

1 टिप्पणियां

 
GN⁺ 2025-08-26
Hacker News की राय
  • यह लेख और HN टिप्पणियाँ, दोनों, Big O Notation को समझाने और उसके व्यावहारिक उपयोग व तकनीकी बारीकियों पर बहस करने की परंपरा को आगे बढ़ा रहे हैं। देखने लायक उदाहरण के तौर पर यह व्याख्यात्मक लेख और विशेषज्ञों के रवैये पर यह लेख हैं

    • पिछली पोस्ट की टिप्पणियाँ देखें तो Pyon नाम के यूज़र ने काफ़ी कटु और अनम्य रवैया दिखाया था। लेकिन Ned की प्रतिक्रिया भी बहुत शानदार नहीं थी। उन्होंने तकनीकी विवरणों को ठीक-ठीक समझाने के बजाय बस “कुछ विशेष बारीकियाँ” जैसा कहकर बात घुमाई-सी लगी। यह भी अफ़सोसजनक है कि उन्होंने यह साफ़ नहीं किया कि उसकी आलोचना सिर्फ़ बेवजह की आपत्ति क्यों थी, और फिर सामग्री को ही क्यों ठुकराया गया। Ned ऑनलाइन संवाद और सहानुभूति के मामले में सही दिशा ज़रूर दिखाते हैं। फिर भी, एक शिक्षक के नाते उन्हें कम-से-कम एक बार यह बताना चाहिए था कि वह तकनीकी बिंदु ज़रूरत से ज़्यादा सूक्ष्म या बेकार की आपत्ति क्यों था। Ned ने बस इतना कहा कि “मुझे खुद दशकों तक यह पता नहीं था”, इसलिए वह बात पर्याप्त नहीं लगी। और मूल टिप्पणी थ्रेड फिर से देखने पर लगा कि Ned ने वास्तव में काफ़ी कूटनीतिक और गंभीर तरीके से बहस की थी। इसलिए यह समझ नहीं आता कि ब्लॉग पोस्ट में वह विश्लेषण क्यों गायब था। निजी तौर पर मुझे भी ठीक-ठीक नहीं पता कि वे तकनीकी बारीकियाँ क्या थीं, लेकिन अच्छा होता अगर एक बार उनका छोटा-सा सार समझा दिया जाता
    • मैं ख़ुद को आलोचनात्मक विशेषज्ञों के क़रीब मानता हूँ। जब भी ब्लॉग पर किसी जटिल विषय को सिखाने की कोशिश देखता हूँ, अक्सर निराश होता हूँ, क्योंकि ज़्यादातर बार गैर-विशेषज्ञ समझाते हुए शुद्धता खो देते हैं। नतीजा यह होता है कि 1) ग़लत या अधूरी बातें इंटरनेट पर जगह-जगह कॉपी-पेस्ट होती रहती हैं, और 2) पाठक सिर्फ़ ब्लॉग-स्तर की समझ पर रुक जाते हैं और आगे सीखने की कोशिश नहीं करते, जिससे उनकी अज्ञानता और मज़बूत हो जाती है। और एक अतिरिक्त बात, मुझे पेज का लेआउट भी पसंद नहीं आया। ADHD और कमज़ोर स्मृति के अपने अनुभव से कहूँ तो, ठीक फ़ॉर्मैटिंग—जैसे उपशीर्षक/बोल्ड/अलग रंग/बुलेट—के साथ बातों को तोड़ा जाए तो ही मैं साथ चल पाता हूँ, लेकिन यह लेख बस टेक्स्ट की दीवार जैसा लगा। मुख्य बात समझने में जितना ज़्यादा समय लगे, उतना ही ध्यान टूटता है। Simple Wikipedia का Big O विवरण काफ़ी ज़्यादा सीधा है। दूसरी ओर, औपचारिक Wikipedia पेज में अचानक गणित सामने आ जाती है, और उसे सीधे पढ़कर महसूस होता है कि Big O असल में सोच से कहीं अधिक जटिल विषय है, जिससे आख़िरकार यही लगता है कि “बहुत ज़्यादा सरल बनाना शायद अच्छा नहीं होगा”
    • दूसरा लिंक Big-O के बारे में नहीं है, और उस तरह का रवैया अपनाने की ज़रूरत नहीं है
    • Ned ने कुछ दिन पहले मुझे ईमेल भेजा था, और अच्छा लग रहा है कि मैं भी ऐसी चर्चाओं में योगदान दे रहा हूँ
    • ऐसे लेखों से असली सीख यह होनी चाहिए कि “अगर कोई व्याख्या ग़लत या भ्रामक है, तो सुधारना बंद कर दो” नहीं, बल्कि यह कि ऑनलाइन कुछ ‘विशेषज्ञ’ सिर्फ़ बहस जीतना चाहते हैं। Pyon का रवैया काफ़ी आक्रामक था और इंटरनेट ट्रोल जैसा लगा। लेकिन इससे कभी यह निष्कर्ष नहीं निकालना चाहिए कि “तो तकनीकी बारीकियाँ मायने नहीं रखतीं और अशुद्ध होना भी ठीक है”
  • O(1) वास्तव में hashing function का उपयोग करता है, जो पूरी तरह सरल नहीं होता, लेकिन उसका ऑपरेशन कॉस्ट स्थिर रहता है। अगर डेटा बहुत कम हो, तो O(n^2) जैसे सबसे खराब एल्गोरिद्म भी वास्तविक समय में ज़्यादा तेज़ हो सकते हैं

    • बात सही है, लेकिन इसे बहुत ज़ोर-शोर से नहीं कहना चाहिए। व्यवहारिक काम में लोगों को सिर्फ़ यह समझाना ही मुश्किल होता है कि n^2 होने पर कंप्यूटर ठहर-सा सकता है। और कुछ मामलों में mod जैसी perfect hash function भी इस्तेमाल की जा सकती है
  • लगता है कि Big-O की आधुनिक महत्ता पहले जैसी नहीं रही। आज का हार्डवेयर multithread, pipeline, NUMA, जटिल caching वगैरह से भरा है, इसलिए कुछ ऑपरेशन एक cycle से भी कम में पूरे हो सकते हैं, जबकि दूसरे सैकड़ों या हज़ारों cycle ले सकते हैं। अगर एल्गोरिद्म को सिर्फ़ innermost loop की गिनती से समझाने की कोशिश करें, तो उल्टा वास्तविकता विकृत हो जाती है। और Big-O की बात करें तो Big-Omega जैसी दूसरी notation का ज़िक्र भी ज़रूर होना चाहिए। (वैसे Big-O पर बनी animation भी मुझे काफ़ी मज़ेदार लगी)

    • Big-O सिद्धांत का जन्म ही ऐसे device-dependent तत्वों से परे ऑपरेशन की मात्रा को परिभाषित करने के लिए हुआ था। इस अर्थ में यह समय से परे एक उपयोगी औज़ार है। (और कोई अच्छा presenter आमतौर पर यह ज़रूर बता देता है कि “C जैसे constant, N छोटा होने पर, बेहद महत्वपूर्ण हो जाते हैं”)
  • सच में दिलचस्प बात यह है कि quantum computing में कुछ ऑपरेशन परमाणुओं की संख्या के साथ O(n^7) की दर से बढ़ते हैं, फिर भी वैज्ञानिक उन्हें वास्तव में चलाने से डरते नहीं हैं। वजह यह है कि N काफ़ी छोटा होता है, कंप्यूटर और memory लगातार तेज़ होते जा रहे हैं, और परिणाम बेहद मूल्यवान होते हैं। (मैं computer science का विशेषज्ञ नहीं हूँ, इसलिए अगर मैंने O() notation ग़लत इस्तेमाल की हो तो क्षमा करें)

    • आप बस यह कह सकते हैं कि “यह n^7 के अनुपात में बढ़ता है।” O(n^7) कहने पर ज़्यादातर लोग समझ जाते हैं, लेकिन गणितीय रूप से O सिर्फ़ ‘upper bound’ दिखाता है, इसलिए वह पूरी तरह सख़्ती से सही नहीं है। अगर बिल्कुल सटीक बोलना हो, तो Ω(n^7) जैसा लिखना अधिक उचित होगा
  • यह visualization मुझे सच में बहुत पसंद आई। पहले एल्गोरिद्म पढ़ चुका हूँ, फिर भी चीज़ों को दृश्य रूप में देखना अभी भी बहुत मददगार लगता है

  • शायद इसलिए कि मैंने electrical engineering पढ़ी है, मुझे हमेशा लगा कि Big O Notation को कुछ ऐसे पढ़ाया जाता है जैसे उसमें बहुत कुछ बस छोड़ दिया गया हो। इसे हमेशा ऐसे लिया गया जैसे यह तो सबको पहले से मालूम होना चाहिए, इसलिए बहुत दोस्ताना ढंग से समझाया हुआ शायद ही कभी देखा। जिज्ञासा है कि किस स्तर के गणित या computer science कोर्स में यह अवधारणा पहली बार ठीक से पढ़ाई जाती है

    • मैंने computer science के Discrete Math कोर्स में Big-O सबसे व्यवस्थित तरीके से सीखा था
    • मेरे कॉलेज में Algorithm Analysis (अनिवार्य कोर्स) में Big-O और कई proof techniques सिखाई जाती थीं। हालाँकि यह ज़्यादातर तीसरे या चौथे साल का कोर्स था, और एक अनकही धारणा यह थी कि छात्र पहले साल तक किसी-न-किसी तरह इस अवधारणा को पहले ही कुछ हद तक आत्मसात कर चुके होंगे (शायद माहौल से अपने-आप सीख लिया होगा)
    • गणितीय रूप से, किसी फलन f(x) का O(g(x)) होना यह बताता है कि f(x)/g(x) किसी स्थिरांक C के लिए “सभी x पर f(x)/g(x) < C” को संतुष्ट करता है। computer science में f(x) अक्सर किसी एल्गोरिद्म की complexity, जैसे ऑपरेशन की संख्या, को दर्शाता है
    • Big-O Notation की रचना की कई तरह से व्याख्या की जा सकती है। उदाहरण के लिए, अगर किसी एल्गोरिद्म को Turing Machine के execution steps की संख्या से परिभाषित करें, तो log-time algorithm जैसी चीज़ हो ही नहीं सकती और O(log n) को O(1) माना जाएगा
    • यह मैंने computer science के पहले साल के अनिवार्य कोर्स में सीखा था। इसमें कोई बड़ी बात नहीं, बस यह बताया जाता है कि input data बढ़ने पर ऑपरेशन की मात्रा कैसे बढ़ती है। ऊपर से मुश्किल दिखता है, लेकिन असल में बहुत सरल और साफ़ अवधारणा है
  • dynamic visualization ने समझने में बहुत बड़ी मदद की। उम्मीद है कि इस तरह के और lessons/resources बनाए जाएँगे

    • यह प्रतिक्रिया सच में सुखद है, धन्यवाद
  • जब भी Big-O Notation पर कोई थ्रेड आता है, मैं उम्मीद करता हूँ कि शायद कोई समझाए कि इसका anime The Big O से क्या संबंध है। आज तक मुझे ठीक से समझ नहीं आया कि वह anime आखिर था किस बारे में

    • (बीयर के 4 कैन गटकने के बाद)अच्छा सुनो। वह anime कुछ ऐसा है जैसे Pacific Rim, Dark City, और The Matrix—इन तीनों को क्रम से मिलाकर बना दिया गया हो
  • मेरे हिसाब से Big O Notation को सबसे प्रभावी ढंग से समझने का तरीका है इसे रोज़मर्रा की ज़िंदगी की उपमाओं से जोड़ना

  • मुझे यह सामग्री बहुत सुंदर लगी। मैंने एक सिग्नल भेजा था, उम्मीद है पहुँच गया होगा, और अजीब-सी खुशी में जैसे थोड़ा डोपामिन मिल गया हो

    • हाँ, पहुँच गया। धन्यवाद