स्मृति को बचाने के लिए चर के लिए छोटे डेटा प्रकारों का उपयोग करना एक अच्छा अभ्यास है?


32

जब मैंने पहली बार C ++ भाषा सीखी तो मैंने जाना कि int, float आदि के अलावा, इन डेटा प्रकारों के छोटे या बड़े संस्करण भाषा के भीतर मौजूद थे। उदाहरण के लिए मैं एक चर x कह सकता हूं

int x;
or 
short int x;

मुख्य अंतर यह है कि शॉर्ट इंट 2 मेमोरी बाइट लेता है, जबकि इंट 4 बाइट लेता है, और शॉर्ट इंट का मूल्य कम होता है, लेकिन हम इसे और भी छोटा बनाने के लिए कह सकते हैं:

int x;
short int x;
unsigned short int x;

जो और भी अधिक प्रतिबंधक है।

यहाँ मेरा प्रश्न यह है कि यदि प्रोग्राम के भीतर आपके वैरिएबल को किन मूल्यों के अनुसार अलग-अलग डेटा प्रकारों का उपयोग करना अच्छा है। क्या इन डेटा प्रकारों के अनुसार हमेशा चर घोषित करना एक अच्छा विचार है?


3
क्या आप फ्लाईवेट डिज़ाइन पैटर्न से अवगत हैं ? "एक वस्तु जो अन्य समान वस्तुओं के साथ जितना संभव हो उतना डेटा साझा करके मेमोरी उपयोग को कम करती है; यह बड़ी संख्या में वस्तुओं का उपयोग करने का एक तरीका है जब एक सरल दोहराया प्रतिनिधित्व स्मृति की अस्वीकार्य राशि का उपयोग करेगा ..."
gnat

5
मानक पैकिंग / संरेखण संकलक सेटिंग्स के साथ, चर को 4 बाइट सीमाओं से किसी भी तरह संरेखित किया जाएगा, इसलिए किसी भी अंतर से नहीं हो सकता है।
nikie

36
समयपूर्व अनुकूलन का क्लासिक मामला।
स्कारफ्रिज

1
@ मिनी - उन्हें x86 प्रोसेसर पर 4 बाइट सीमा पर संरेखित किया जा सकता है, लेकिन यह सामान्य रूप से सच नहीं है। MSP430 किसी भी बाइट पते पर चार और एक बाइट पते पर बाकी सब कुछ करता है। मुझे लगता है कि AVR-32 और ARM Cortex-M एक ही हैं।
अपराह्न

3
आपके प्रश्न का दूसरा भाग यह बताता है कि unsignedकिसी तरह जोड़ने से पूर्णांक कम जगह घेरता है, जो निश्चित रूप से गलत है। इसमें असतत प्रतिनिधित्व योग्य मानों की समान संख्या होगी (संकेत कैसे दर्शाए गए हैं इसके आधार पर 1 दें या लें) लेकिन केवल विशेष रूप से सकारात्मक में स्थानांतरित किया गया।
अंडरस्कोर_ड

जवाबों:


41

अधिकांश समय अंतरिक्ष की लागत नगण्य है और आपको इसके बारे में चिंता नहीं करनी चाहिए, हालांकि आपको एक प्रकार की घोषणा करके अतिरिक्त जानकारी के बारे में चिंता करनी चाहिए। उदाहरण के लिए, यदि आप:

unsigned int salary;

आप किसी अन्य डेवलपर को उपयोगी जानकारी दे रहे हैं: वेतन नकारात्मक नहीं हो सकता।

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


5
इसका सच यह शायद ही कभी इन दिनों समस्याओं का कारण बनने जा रहा है, लेकिन अगर आप एक पुस्तकालय या एक वर्ग डिजाइन कर रहे हैं जो एक और डेवलपर उपयोग करेगा, तो यह अच्छी बात है। हो सकता है कि उन्हें इन वस्तुओं के एक लाख के लिए भंडारण की आवश्यकता होगी, जिस स्थिति में अंतर बड़ा है - 4MB 2MB की तुलना में सिर्फ इस एक क्षेत्र के लिए।
dodgy_coder

30
unsignedइस मामले में उपयोग करना एक बुरा विचार है: न केवल वेतन नकारात्मक हो सकता है, बल्कि दो वेतन के बीच का अंतर भी नकारात्मक नहीं हो सकता है। (सामान्य तौर पर, कुछ के लिए अहस्ताक्षरित का उपयोग करते हुए, बिट-ट्विडलिंग और अतिप्रवाह पर परिभाषित व्यवहार होना एक बुरा विचार है।)
zvrba

15
@ ज़र्बा: दो वेतन के बीच का अंतर स्वयं एक वेतन नहीं है और इसलिए यह हस्ताक्षरित एक अलग प्रकार का उपयोग करने के लिए वैध है।
जेरेमीपीप

12
@JeremyP हां, लेकिन यदि आप C का उपयोग कर रहे हैं (और ऐसा लगता है कि यह C ++ में भी सच है), अहस्ताक्षरित पूर्णांक घटाव एक अहस्ताक्षरित परिणाम में है , जो नकारात्मक नहीं हो सकता। यदि आप इसे हस्ताक्षरित इंट में डालते हैं तो यह सही मूल्य में बदल सकता है, लेकिन गणना का परिणाम एक अहस्ताक्षरित इंट है। अधिक हस्ताक्षरित / अहस्ताक्षरित संगणना अजीबता के लिए इस उत्तर को भी देखें - यही कारण है कि आपको कभी भी अहस्ताक्षरित चर का उपयोग नहीं करना चाहिए जब तक कि आप वास्तव में चक्कर नहीं काट रहे हों।
टैक्रॉय

5
@ ज़र्बा: अंतर एक मौद्रिक मात्रा है, लेकिन वेतन नहीं। अब आप यह तर्क दे सकते हैं कि वेतन भी एक मौद्रिक मात्रा है (सकारात्मक संख्याओं के लिए बाध्य और 0 इनपुट को मान्य करके जो ज्यादातर लोग करते हैं) लेकिन दो वेतन के बीच का अंतर स्वयं वेतन नहीं है।
जेरेमीपीप

29

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

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

मैं वर्तमान में 32-बिट MIPS- आधारित माइक्रोकंट्रोलर के साथ एक और एम्बेडेड प्रोजेक्ट कर रहा हूं जिसमें 512K बाइट्स फ्लैश और 128K बाइट्स RAM (और इसकी कीमत लगभग $ 6 है)। एक पीसी के साथ के रूप में, "प्राकृतिक" डेटा का आकार 32-बिट्स है। अब यह अधिक कुशल, कोड-वार हो जाता है, चार्ट या शॉर्ट्स के बजाय अधिकांश चर के लिए ints का उपयोग करने के लिए। लेकिन एक बार फिर, किसी भी प्रकार की सरणी या संरचना पर विचार किया जाना चाहिए कि क्या छोटे डेटा प्रकार वारंट हैं। बड़ी प्रणालियों के लिए संकलक के विपरीत, यह अधिक संभावना है कि एक संरचना में चर एक एम्बेडेड सिस्टम पर पैक किया जाएगा । मैं हमेशा सभी 32-बिट चर को पहले रखने की कोशिश करता हूं, फिर 16-बिट, फिर 8-बिट किसी भी "छेद" से बचने के लिए।


10
+1 इस तथ्य के लिए कि विभिन्न नियम एम्बेडेड सिस्टम पर लागू होते हैं। तथ्य यह है कि सी ++ का उल्लेख किया गया है इसका मतलब यह नहीं है कि लक्ष्य एक पीसी है। मेरी हालिया परियोजनाओं में से एक C ++ में 32k RAM और फ्लैश के 256K के साथ एक प्रोसेसर पर लिखा गया था।
u

13

उत्तर आपके सिस्टम पर निर्भर करता है। आमतौर पर, यहां छोटे प्रकार के उपयोग के फायदे और नुकसान हैं:

लाभ

  • अधिकांश सिस्टम पर छोटे प्रकार कम मेमोरी का उपयोग करते हैं।
  • छोटे प्रकार कुछ प्रणालियों पर तेजी से गणना करते हैं। कई प्रणालियों पर फ्लोट बनाम डबल के लिए विशेष रूप से सच है। और छोटे इंट प्रकार भी 8- या 16-बिट सीपीयू पर काफी तेज कोड देते हैं।

नुकसान

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

मेरी सलाह इस तरह है:

system                             int types

small/low level embedded system    stdint.h with smaller types
32-bit embedded system             stdint.h, stick to int32_t and uint32_t.
32-bit desktop system              Only use (unsigned) int and long long.
64-bit system                      Only use (unsigned) int and long long.

वैकल्पिक रूप से, आप stdint.h से int_leastn_tया int_fastn_tजहां n 8, 16, 32 या 64 नंबर का उपयोग कर सकते हैं । int_leastn_tप्रकार का अर्थ है "मैं चाहता हूं कि यह कम से कम n बाइट्स हो लेकिन मुझे परवाह नहीं है कि कंपाइलर इसे आवंटित करता है या नहीं संरेखण के लिए एक बड़ा प्रकार "।

int_fastn_t इसका मतलब है "मैं चाहता हूं कि यह एन बाइट्स लंबा हो, लेकिन अगर यह मेरे कोड को तेजी से चलाएगा, तो कंपाइलर को निर्दिष्ट से बड़े प्रकार का उपयोग करना चाहिए"।

आमतौर पर, विभिन्न stdint.h प्रकार सादे intआदि की तुलना में बहुत बेहतर अभ्यास हैं , क्योंकि वे पोर्टेबल हैं। इसका उद्देश्य intकेवल इसे पोर्टेबल बनाने के लिए इसे निर्दिष्ट चौड़ाई नहीं देना था। लेकिन वास्तव में, यह पोर्ट करना कठिन है क्योंकि आप कभी नहीं जानते कि यह किसी विशिष्ट सिस्टम पर कितना बड़ा होगा।


संरेखण के बारे में स्पॉट। मेरी वर्तमान परियोजना में, 16-बिट MSP430 पर uint8_t के गंभीर उपयोग ने रहस्यमय तरीके से MCU को दुर्घटनाग्रस्त कर दिया (सबसे अधिक संभावना है कि कहीं गलत उपयोग हुआ, शायद जीसीसी की गलती, शायद नहीं) - 'uint8_t' को 'अहस्ताक्षरित' से बदलकर दुर्घटनाओं को समाप्त कर दिया। 8-बिट प्रकारों पर> 8-बिट आर्क का उपयोग करें यदि घातक नहीं है तो कम से कम अक्षम है: संकलक अतिरिक्त उत्पन्न करता है 'और reg, 0xff' निर्देश। पोर्टेबिलिटी के लिए 'int / अहस्ताक्षरित' का उपयोग करें और संकलक को अतिरिक्त बाधाओं से मुक्त करें।
अलेई

11

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

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

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

यदि आपके पास कुछ बहुत सख्त डेटा आवश्यकताएं हैं, जैसे कि संचार प्रोटोकॉल लिखना, या किसी प्रकार का एन्क्रिप्शन एल्गोरिथम, तो रेंज-चेक किए गए डेटाटिप्स का उपयोग करना बहुत काम में आ सकता है, खासकर यदि आप डेटा ओवररन / अंडरग्रंज से संबंधित समस्याओं से बचने की कोशिश कर रहे हैं या अमान्य डेटा मान।

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


6

जैसा कि स्कारफ्रिज ने टिप्पणी की, यह एक है

समयपूर्व अनुकूलन का क्लासिक मामला ।

स्मृति उपयोग के लिए अनुकूलन करने का प्रयास प्रदर्शन के अन्य क्षेत्रों को प्रभावित कर सकता है , और अनुकूलन के सुनहरे नियम हैं:

कार्यक्रम अनुकूलन का पहला नियम: यह मत करो

कार्यक्रम अनुकूलन का दूसरा नियम (केवल विशेषज्ञों के लिए!): अभी तक ऐसा न करें । "

- माइकल ए जैक्सन

यह जानने के लिए कि अब अनुकूलन का समय है, बेंचमार्किंग और परीक्षण की आवश्यकता है। आपको यह जानना होगा कि आपका कोड कहां अक्षम है, ताकि आप अपनी आशाओं को लक्षित कर सकें।

यह निर्धारित करने के लिए कि क्या कोड का अनुकूलित संस्करण वास्तव में किसी भी समय अनुभवहीन कार्यान्वयन से बेहतर है, आपको उन्हें समान डेटा के साथ साइड-बाय-साइड बेंचमार्क करना होगा।

यह भी याद रखें कि सिर्फ इसलिए कि एक दिया गया कार्यान्वयन CPU की वर्तमान पीढ़ी पर अधिक कुशल है, इसका मतलब यह नहीं है कि यह हमेशा ऐसा रहेगा । प्रश्न का मेरा उत्तर क्या कोडिंग करते समय सूक्ष्म अनुकूलन महत्वपूर्ण है? व्यक्तिगत अनुभव से एक उदाहरण का विवरण करें जहां अप्रचलित अनुकूलन के परिणामस्वरूप परिमाण मंदी का क्रम था।

कई प्रोसेसरों पर, बिना मेमोरी मेमोरी एक्सेस संरेखित मेमोरी एक्सेस की तुलना में काफी अधिक महंगा है। अपनी संरचना में शॉर्ट्स के एक जोड़े को पैक करने का मतलब सिर्फ यह हो सकता है कि आपके प्रोग्राम को हर बार या तो मूल्य को छूने के लिए पैक / अनपैक ऑपरेशन करना है ।

इस कारण से, आधुनिक संकलनकर्ता आपके सुझावों की उपेक्षा करते हैं। निक्की टिप्पणी के रूप में :

मानक पैकिंग / संरेखण संकलक सेटिंग्स के साथ, चर को 4 बाइट सीमाओं से किसी भी तरह संरेखित किया जाएगा, इसलिए किसी भी अंतर से नहीं हो सकता है।

दूसरा आपके कंपाइलर पर आपके कंपाइलर का अनुमान लगाता है।

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


3

मुख्य अंतर यह है कि शॉर्ट इंट 2 मेमोरी बाइट लेता है, जबकि इंट 4 बाइट लेता है, और शॉर्ट इंट का मूल्य कम होता है, लेकिन हम इसे और भी छोटा बनाने के लिए कह सकते हैं:

यह गलत है। आप यह अनुमान नहीं लगा सकते हैं कि प्रत्येक बाइट कितने प्रकार की होती है, charबाइट होने के अलावा और बाइट प्रति कम से कम 8 बिट्स के साथ होती है, साथ ही प्रत्येक प्रकार का आकार पिछले से अधिक या बराबर होता है।

स्टैक चर के लिए प्रदर्शन के लाभ अविश्वसनीय रूप से छोटे हैं - वे वैसे भी गठबंधन / गद्देदार होंगे।

इस वजह से, shortऔर longव्यावहारिक रूप से आजकल कोई उपयोग नहीं है, और आप लगभग हमेशा बेहतर उपयोग कर रहे हैं int


बेशक, वहाँ भी है stdint.hजो intइसे काटने के लिए उपयोग करने के लिए पूरी तरह से ठीक है। यदि आप कभी भी पूर्णांक / संरचना के विशाल सरणियों को आवंटित कर रहे हैं तो एक intX_tसमझ में आता है क्योंकि आप कुशल हो सकते हैं और प्रकार के आकार पर भरोसा कर सकते हैं। यह सभी समय से पहले नहीं है क्योंकि आप मेगाबाइट्स मेमोरी को बचा सकते हैं।


1
दरअसल, 64 बिट वातावरण के आगमन के साथ longभिन्न हो सकते हैं int। यदि आपका कंपाइलर LP64 है, int32 बिट्स है और long64 बिट्स है और आप पाएंगे कि ints अभी भी 4 बाइट्स एलायंस हो सकता है (उदाहरण के लिए मेरा कंपाइलर करता है)।
जेरेमीपप

1
@JeremyP हाँ, मैंने कहा अन्यथा या कुछ और?
पबबी

आपका अंतिम वाक्य जो छोटा और लंबा दावा करता है, व्यावहारिक रूप से इसका कोई उपयोग नहीं है। लंबे समय से निश्चित रूप से एक उपयोग होता है, यदि केवल आधार प्रकार के रूप मेंint64_t
जेरेमीप

@ जेरेमीप: आप इंट और लंबे लंबे समय तक ठीक रह सकते हैं।
gnasher729

@ gnasher729: अगर आपको ऐसे वेरिएबल की जरूरत है जो 65 हजार से ज्यादा वैल्यू होल्ड कर सके, लेकिन एक बिलियन जितना कभी नहीं होगा तो आप क्या इस्तेमाल करेंगे? int32_t, int_fast32_tऔर longसभी अच्छे विकल्प हैं, long longबस बेकार है, और intगैर-पोर्टेबल है।
बेन वोइगट

3

यह एक प्रकार का OOP और / या enterprisey / एप्लिकेशन पॉइंट ऑफ़ व्यू से होगा और कुछ फ़ील्ड्स / डोमेन में लागू नहीं हो सकता है, लेकिन मैं एक तरह से प्राइमरी ऑब्सेशन का कॉन्सेप्ट लाना चाहता हूं ।

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

यदि हम अपने आवेदन में केल्विन में तापमान को मॉडल करना चाहते हैं, तो हम COULD एक ushortया uintकुछ इसी तरह का उपयोग करते हैं कि यह दर्शाता है कि "नकारात्मक डिग्री केल्विन की धारणा बेतुकी है और एक डोमेन लॉजिक त्रुटि है"। इसके पीछे विचार ध्वनि है, लेकिन आप बिल्कुल नहीं जा रहे हैं। हमें एहसास हुआ कि हमारे पास नकारात्मक मूल्य नहीं हो सकते हैं, इसलिए यह आसान है अगर हम यह सुनिश्चित करने के लिए संकलक प्राप्त कर सकते हैं कि कोई भी केल्विन तापमान को नकारात्मक मूल्य प्रदान नहीं करता है। यह भी सही है कि आप तापमान पर बिटवाइज़ ऑपरेशन नहीं कर सकते। और आप तापमान (K) के लिए वजन (किलो) की माप नहीं जोड़ सकते। लेकिन अगर आप तापमान और द्रव्यमान को uintएस के रूप में मॉडल करते हैं , तो हम ऐसा कर सकते हैं।

हमारे DOMAIN संस्थाओं को मॉडल करने के लिए अंतर्निहित प्रकारों का उपयोग करने के लिए कुछ गंदे कोड और कुछ छूटे हुए चेक और टूटे हुए इनवेरिएंट का नेतृत्व करने के लिए बाध्य है। यहां तक ​​कि अगर एक प्रकार इकाई के कुछ हिस्से को कैप्चर करता है (नकारात्मक नहीं हो सकता है), यह दूसरों को याद करने के लिए बाध्य है (मनमाने ढंग से अंकगणितीय अभिव्यक्तियों में इस्तेमाल नहीं किया जा सकता है, बिट्स की एक सरणी के रूप में नहीं माना जा सकता है, आदि)

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


1

हां बिल्कुल। इसका इस्तेमाल करने के अच्छा विचार है uint_least8_tशब्दकोशों के लिए, विशाल स्थिरांक सरणियों, बफ़र्स आदि यह उपयोग करने के लिए बेहतर है uint_fast8_tप्रसंस्करण प्रयोजनों के लिए।

uint8_least_t(भंडारण) -> uint8_fast_t(प्रसंस्करण) -> uint8_least_t(भंडारण)।

उदाहरण के लिए आप 8 बिट्स प्रतीक से source, 16 बिट कोड से dictionariesऔर कुछ 32 बिट से ले रहे हैं constants। की तुलना में आप उनके साथ 10-15 बिट संचालन संसाधित कर रहे हैं और 8 बिट आउटपुट करते हैं destination

आइए कल्पना करें कि आपको 2 गीगाबाइट की प्रक्रिया करनी है source। बिट संचालन की मात्रा बहुत बड़ी है। यदि आप प्रसंस्करण के दौरान तेजी से प्रकारों पर स्विच करेंगे, तो आपको बढ़िया इत्र बोनस मिलेगा। प्रत्येक सीपीयू परिवार के लिए फास्ट प्रकार भिन्न हो सकते हैं। आप शामिल कर सकते हैं stdint.hऔर उपयोग uint_fast8_t, uint_fast16_t, uint_fast32_t, आदि

आप पोर्टेबिलिटी के uint_least8_tबजाय उपयोग कर सकते हैं uint8_t। लेकिन वास्तव में कोई भी नहीं जानता है कि आधुनिक सीपीयू इस सुविधा का उपयोग करेगा। वीएसी मशीन एक संग्रहालय का टुकड़ा है। तो शायद यह एक overkill है।


1
जब आपके पास सूचीबद्ध डेटा प्रकारों के साथ एक बिंदु हो सकता है, तो आपको यह समझाना चाहिए कि वे केवल यह बताते हुए बेहतर क्यों हैं कि क्या हैं। मेरे जैसे लोगों के लिए जो उन डेटा प्रकारों से अपरिचित हैं, मुझे यह समझने के लिए उन्हें Google करना पड़ा कि आप किस बारे में बात कर रहे हैं।
पीटर एम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.