सबसे पहले, समस्या if
नहीं है; जैसा कि आपने देखा, gcc
if
के माध्यम से देखता है और 30
को सीधे printf
पास करने का प्रबंधन करता है।
अब, gcc
कुछ तर्क printf
के विशेष मामलों को संभालने के लिए है (विशेष रूप से, यह printf("something\n")
और यहां तक कि printf("%s\n", "something")
puts("something")
करने का अनुकूलन करता है), लेकिन यह अत्यंत विशिष्ट है और बहुत आगे जाना नहीं करता है; printf("Hello %s\n", "world")
, उदाहरण के लिए, के रूप में छोड़ दिया गया है। इससे भी बदतर, से ऊपर के किसी भी प्रकार के के बिना किसी भी पिछली नई रेखा को छूटा नहीं जाता है, भले ही उन्हें fputs("something", stdout)
में परिवर्तित किया जा सके।
मैं कल्पना है कि इस दो मुख्य समस्याओं के लिए नीचे आता है:
दो मामलों ऊपर लागू करने और अक्सर होने के लिए बहुत आसान पैटर्न हैं, लेकिन बाकी शायद के लिए यह शायद ही कभी प्रयास के लायक है, यदि स्ट्रिंग स्थिर है और प्रदर्शन महत्वपूर्ण है, तो प्रोग्रामर आसानी से इसका ख्याल रख सकता है - वास्तव में, यदि printf
का प्रदर्शन महत्वपूर्ण है तो उसे इस तरह के अनुकूलन पर भरोसा नहीं करना चाहिए, जो प्रारूप के मामूली परिवर्तन को तोड़ सकता है स्ट्रिंग।
यदि आप मुझसे पूछते हैं, तो ऊपर दिए गए puts
ऑप्टिमाइज़ेशन पहले से ही "स्टाइल पॉइंट्स के लिए जा रहे हैं", आप वास्तव में कुछ भी कृत्रिम परीक्षण मामलों में गंभीर प्रदर्शन नहीं कर पाएंगे।
जब आप %s\n
के दायरे से बाहर जाना शुरू करते हैं, printf
एक minefield है, क्योंकि यह रनटाइम पर्यावरण पर मजबूत निर्भरता है; विशेष रूप से, कई printf
विनिर्देशक (दुर्भाग्य से) लोकेल से प्रभावित होते हैं, साथ ही कार्यान्वयन-विशिष्ट क्विर्क और विनिर्देशकों का एक उछाल होता है (और gcc
glibc, musl, mingw/msvcrt, से printf
के साथ काम कर सकता है ...- और संकलन समय पर आप लक्ष्य सी रनटाइम का आह्वान नहीं कर सकते - सोचें कि जब आप क्रॉस-कंपाइलिंग करते हैं)।
मैं मानता हूं कि यह आसान %d
केस शायद सुरक्षित है, लेकिन मैं देख सकता हूं कि उन्होंने शायद अधिकतर स्मार्ट होने से बचने का फैसला क्यों किया और केवल यहां सबसे कमजोर और सुरक्षित अनुकूलन निष्पादित किए।
उत्सुक पाठक के लिए, here जहां इस अनुकूलन वास्तव में कार्यान्वित किया जाता है है; जैसा कि आप देख सकते हैं, फ़ंक्शन बहुत ही सरल मामलों की सीमित संख्या से मेल खाता है (और एक तरफ गिंपल, this nice article के बाद से बहुत कुछ नहीं बदला है)। संयोग से, स्रोत वास्तव में बताता है कि वे गैर-न्यूलाइन मामले के लिए fputs
संस्करण को कार्यान्वित क्यों नहीं कर सके (उस संकलन चरण में stdout
वैश्विक संदर्भित करने का कोई आसान तरीका नहीं है)।
स्रोत
2016-05-26 23:47:56
'gcc'' printf' आउटपुट की भविष्यवाणी नहीं कर सकता (नहीं ..?)। – LPs
@ एलपी AFAIK, यह printf() को कॉल() और putchar() जहां कॉल संभव हो, कॉल के साथ कॉल बदलता है। – Mitsos101
@ मित्सोस 101 केवल * ज्ञात संकलन-समय स्थिरांक * के साथ। जो आप अपने कोड में देख रहे हैं उसे केवल इसे चलाकर निर्धारित किया जा सकता है। आपके सिर में करने के लिए आसान - एक कंपाइलर के लिए कम आसान है। – adelphus