हमें गति के लिए अमूर्त व्यापार क्यों करना है?


11

उच्च-स्तरीय भाषाओं को गति के मामले में निम्न-स्तरीय भाषाओं तक क्यों नहीं पहुंचाया जा सकता है? उच्च-स्तरीय भाषाओं के उदाहरण पायथन, हास्केल और जावा होंगे। निम्न-स्तरीय भाषाओं को परिभाषित करना मुश्किल होगा, लेकिन मान लीजिए कि सी। तुलना इंटरनेट के चारों ओर पाई जा सकती है और वे सभी सहमत हैं कि सी बहुत तेज है, कभी-कभी 10 या उससे अधिक के कारक से।1

ऐसा क्या है जो प्रदर्शन में इतना बड़ा अंतर पैदा करता है और उच्च स्तरीय भाषाएं क्यों नहीं पकड़ पाती हैं?

शुरू में मुझे विश्वास था कि यह सभी संकलक की गलती है और भविष्य में चीजें बेहतर हो जाएंगी, लेकिन कुछ सबसे लोकप्रिय उच्च-स्तरीय भाषाएं दशकों से आसपास हैं और जब भी यह गति आती है, तब भी वे पीछे रह जाती हैं। क्या वे केवल सी सिंटैक्स के पेड़ के समान संकलन नहीं कर सकते हैं और फिर उन्हीं प्रक्रियाओं का पालन करते हैं जो मशीन कोड उत्पन्न करते हैं? या शायद यह सिंटैक्स के साथ ही कुछ करना है?


1 उदाहरण:


5
"और वे सभी सहमत हैं कि सी बहुत तेज है" - यह निश्चित रूप से गलत है।
राफेल

2
वैसे भी, मुझे लगता है कि पोस्ट एक समान रूप से बीमार प्रश्न के मेरे उत्तर से सबसे अच्छा उत्तर दिया गया है ; नकल?
राफेल

2
यहाँ और यहाँ भी देखें । जंक जवाबों से सावधान रहें।
राफेल

प्रासंगिक: stackoverflow.com/questions/6964392/… सभी "उच्च स्तरीय भाषाओं" का मिथक धीमा होना काफी दुखद है।
xji

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

जवाबों:


19

कुछ मिथकों का विमोचन

  1. तेज लंगोटी जैसी कोई बात नहीं है। एक भाषा आम तौर पर तेजी से कोड का उत्पादन कर सकती है, लेकिन विभिन्न भाषाएं अलग-अलग बेंचमार्क पर उत्कृष्टता प्राप्त करेंगी। हम त्रुटिपूर्ण बेंचमार्क के एक विशेष सेट पर भाषाओं को रैंक कर सकते हैं, लेकिन भाषाओं को निर्वात में रैंक नहीं कर सकते।

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

  3. कभी-कभी, यह अनिश्चित है, अमूर्त नहीं है, जो सी को तेज बनाता है। इसके एरे-बाउंड्स और नल-पॉइंटर चेक की कमी से समय की बचत होती है, और यह सालों भर कई सुरक्षा छेदों का कारण रहा है।

  4. भाषाएं तेज़ नहीं हैं, कार्यान्वयन तेज़ हैं। कई अमूर्त भाषाएं धीमी गति से शुरू होती हैं, क्योंकि गति उनका लक्ष्य नहीं है, लेकिन अधिक से अधिक अनुकूलन के रूप में तेज हो जाते हैं।

एब्सट्रैक्ट बनाम स्पीड ट्रेडऑफ शायद गलत है। मैं एक बेहतर तुलना का सुझाव दूंगा:

सादगी, गति, अमूर्तता: दो का चयन करें।

यदि हम अलग-अलग भाषाओं में समान एल्गोरिदम चला रहे हैं, तो गति का प्रश्न "इस काम को करने के लिए रनटाइम पर कितना सामान करने की आवश्यकता है" की समस्या के लिए नीचे आता है?

एक अत्यधिक अमूर्त भाषा में, जो सरल है , जैसे कि पायथन या जावास्क्रिप्ट, क्योंकि हम रनटाइम तक डेटा के प्रतिनिधित्व के बारे में नहीं जानते हैं, वहाँ रन-टाइम पर बहुत सारे पॉइंटर डी-रेफरेंसिंग और डायनेमिक चेक हो रहे हैं, जो धीमे हैं।

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

अंत में, अधिकांश अमूर्त भाषाओं में कचरा संग्रह से ओवरहेड होता है। अधिकांश प्रोग्रामर इस बात से सहमत हैं कि डायनामिक रूप से आवंटित मेमोरी के जीवनकाल को ट्रैक करना एक दर्द है, और वे इसे चलाने के लिए एक कचरा संग्रहकर्ता के पास करते हैं। इसमें समय लगता है, कि C प्रोग्राम को GC पर खर्च करने की आवश्यकता नहीं है।

सार का मतलब धीमी नहीं है

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

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


2
"सी कोड तेज़ हो जाता है क्योंकि जिन लोगों को प्रदर्शन के हर इंच की आवश्यकता होती है वे सी" - बिल्कुल। मैं फॉर्म के बेंचमार्क देखना चाहता हूं "एक्स-ईयर स्टूडेंट्स / प्रोफेशनल्स द्वारा लिखे गए कोड के औसत रनिंग टाइम को Y के अनुभव के साथ Z"। मुझे उम्मीद है कि छोटे X और Y के लिए C का उत्तर आमतौर पर "कोड सही नहीं है"। यह देखने के लिए वास्तव में दिलचस्प होगा कि प्रदर्शन सी वादों की क्षमता का लाभ उठाने के लिए आपको कितना अधिक अनुभव / विशेषज्ञता चाहिए ।
राफेल

हास्केल वास्तव में एक अपवाद है जो नियम को साबित करता है। ;) मुझे लगता है कि सी ++ ने अपने स्मार्ट पॉइंटर्स द्वारा जीसी के बारे में उचित मध्य मैदान पाया है जब तक कि आप साझा पॉइंटर्स को घोंसला नहीं देते हैं और सी के रूप में तेज़ होगा
केव

0

यहाँ इस पर कुछ महत्वपूर्ण विचार हैं।

  • wrt abstraction बनाम गति बनाने के लिए एक आसान तुलना / केस स्टडी java बनाम c ++ है। जावा को c ++ के निचले स्तर के कुछ पहलुओं जैसे कि स्मृति प्रबंधन को अलग करने के लिए डिज़ाइन किया गया था। शुरुआती दिनों में (1990 के दशक के मध्य से भाषा के आविष्कार के आसपास), जावा कचरा का पता लगाने में बहुत तेजी नहीं थी, लेकिन कुछ दशकों के शोध के बाद, कचरा संग्रहकर्ता बेहद सूक्ष्म / तेज / अनुकूलित हैं, इसलिए कचरा संग्रहकर्ता बड़े पैमाने पर हैं जावा पर प्रदर्शन नाली। उदाहरण के लिए यह 1998 की हेडलाइन भी देखें: प्रदर्शन परीक्षण जावा को C ++ / javaworld के रूप में तेज़ दिखाते हैं

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

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


0

जिस तरह से मैं प्रदर्शन के बारे में सोचना पसंद करता हूं वह है "जहां रबर सड़क से मिलता है"। कंप्यूटर निर्देशों को निष्पादित करता है, न कि अमूर्त।

जो मैं देखना चाहता हूं वह यह है: क्या हर निर्देश को निष्पादित किया जाता है, जो अंतिम परिणाम के लिए पर्याप्त योगदान देकर "अपनी कमाई अर्जित करता है"? बहुत सरल उदाहरण के रूप में, 1024 प्रविष्टियों की तालिका में एक प्रविष्टि देखने पर विचार करें। यह एक 10-बिट समस्या है क्योंकि कार्यक्रम को उत्तर जानने से पहले 10 बिट्स को "सीखना" पड़ता है। यदि एल्गोरिथ्म बाइनरी खोज है, तो प्रत्येक पुनरावृत्ति 1 बिट जानकारी का योगदान करती है, क्योंकि यह 2. के कारक द्वारा अनिश्चितता को सिकोड़ती है। इसलिए यह 10 पुनरावृत्तियों को लेती है, प्रत्येक बिट के लिए एक।

दूसरी ओर, रेखीय खोज शुरू में बहुत ही अक्षम है, क्योंकि पहली पुनरावृत्तियाँ एक बहुत छोटे कारक द्वारा अनिश्चितता को कम करती हैं। इसलिए वे खर्च किए गए प्रयास के लिए बहुत कुछ नहीं सीख रहे हैं।

ठीक है, इसलिए यदि कंपाइलर उपयोगकर्ता को "एब्सट्रैक्ट" माने जाने वाले तरीके से अच्छे निर्देशों को लपेटने की अनुमति दे सकता है, तो यह ठीक है।


0

इसकी प्रकृति के आधार पर अमूर्त जानकारी के सांप्रदायिककरण को कम कर देता है, प्रोग्रामर और सिस्टम की निचली परतों (संकलक, लाइब्रेरी और रनटाइम सिस्टम) दोनों के लिए। अमूर्तता के पक्ष में, यह आम तौर पर निचली परतों को यह मानने की अनुमति देता है कि प्रोग्रामर किसी अनिर्दिष्ट व्यवहार से चिंतित नहीं है, निर्दिष्ट व्यवहार की आपूर्ति में अधिक लचीलापन प्रदान करता है।

डेटा लेआउट में इस "परवाह न करें" पहलू से संभावित लाभ का एक उदाहरण है। सी (कम अमूर्त) में, कंपाइलर डेटा लेआउट अनुकूलन में अधिक विवश है। यहां तक ​​कि अगर कंपाइलर डिस्कशन कर सकता है (उदाहरण के लिए, प्रोफ़ाइल जानकारी के माध्यम से) कि हॉट / कोल्ड या गलत-शेयरिंग-अवॉइडेंस ऑप्टिमाइज़ेशन फायदेमंद होगा, तो इसे आमतौर पर ऐसे लगाने से रोका जाता है। (विनिर्देशन को "जैसे कि" निर्दिष्ट करने में कुछ स्वतंत्रता है, अर्थात, विनिर्देश को अधिक सारगर्भित रूप से व्यवहार करना, लेकिन सभी संभावित दुष्प्रभावों को प्राप्त करना कंपाइलर पर बोझ डाल देता है।)

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

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

सूचना छिपाने का प्रभाव दूसरी दिशा में भी काम करता है। हर विस्तार पर विचार करने और निर्दिष्ट नहीं करने से प्रोग्रामर अधिक उत्पादक हो सकता है, लेकिन प्रोग्रामर को उच्च डिज़ाइन डिज़ाइन विकल्पों के प्रभाव के बारे में कम जानकारी हो सकती है।

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

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

विशिष्टता अपने आप को दोहराए जाने के सिद्धांत के खिलाफ भी काम करती है क्योंकि एक विशिष्ट उपयोग के लिए कोड सिलाई द्वारा अनुकूलन आमतौर पर संभव है। इसमें स्पष्ट विश्वसनीयता और प्रोग्रामिंग प्रयास निहितार्थ हैं।

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

भाषा की उम्र और लोकप्रियता दोनों कुशल प्रोग्रामर की उपलब्धता और सिस्टम की निचली परतों की गुणवत्ता (परिपक्व पुस्तकालयों और कोड उदाहरणों सहित) में उल्लेखनीय हैं।

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

(कम अमूर्त भाषाएं, प्रोग्रामर नियंत्रण पर उनके जोर के कारण, आगे-समय संकलन का उपयोग करने का पक्ष लेती हैं। इंस्टॉल-टाइम संकलन को बर्दाश्त किया जा सकता है, हालांकि लिंक-टाइम कार्यान्वयन चयन अधिक प्रोग्रामर नियंत्रण प्रदान करेगा। जेआईटी संकलन बलिदान सांकेतिक नियंत्रण। )

बेंचमार्किंग पद्धति का मुद्दा भी है। समान प्रयास / कौशल को स्थापित करना प्रभावी रूप से असंभव है, लेकिन यहां तक ​​कि ऐसा करने से भाषा के लक्ष्यों को प्राप्त किया जा सकता है। यदि कम अधिकतम प्रोग्रामिंग समय की आवश्यकता होती है, तो एक कम अमूर्त भाषा के लिए एक कार्यक्रम एक और अमूर्त भाषा में एक सरल मुहावरेदार अभिव्यक्ति की तुलना में पूरी तरह से लिखे जाने में भी विफल हो सकता है। यदि एक उच्च अधिकतम प्रोग्रामिंग समय / प्रयास की अनुमति दी गई थी, तो कम-अमूर्त भाषाओं का लाभ होगा। सर्वश्रेष्ठ प्रयास परिणाम प्रस्तुत करने वाले बेंचमार्क स्वाभाविक रूप से कम अमूर्त भाषाओं के पक्षपाती होंगे।

अन्य प्रोग्रामिंग प्रतिमानों के लाभ प्राप्त करने के लिए भाषा में कम मुहावरेदार तरीके से कार्यक्रम करना कभी-कभी संभव होता है, लेकिन जब अभिव्यंजक शक्ति उपलब्ध होती है तो ऐसा करने के लिए ट्रेडऑफ़ उपलब्ध नहीं हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.