साक्षात्कार प्रश्न: कौन सा तेजी से निष्पादित करेगा, if (flag==0)
या if (0==flag)
? क्यों?
if(flag = 0)
थोड़ा पठनीयता की कीमत पर कीड़े के खिलाफ बीमा किया जाता है।
साक्षात्कार प्रश्न: कौन सा तेजी से निष्पादित करेगा, if (flag==0)
या if (0==flag)
? क्यों?
if(flag = 0)
थोड़ा पठनीयता की कीमत पर कीड़े के खिलाफ बीमा किया जाता है।
जवाबों:
मैंने अभी तक कोई सही उत्तर नहीं देखा है (और पहले से ही कुछ) कैविएट हैं: नवाज ने उपयोगकर्ता द्वारा परिभाषित जाल को इंगित किया । और मुझे खेद है कि मैंने जल्दबाजी में "बेवकूफी भरे सवाल" पर उतारू हो गए क्योंकि ऐसा लगता है कि बहुतों को यह सही नहीं लगा और यह कंपाइलर ऑप्टिमाइज़ेशन पर एक अच्छी चर्चा के लिए जगह देता है :)
उत्तर है:
flag
प्रकार क्या है ?
मामले में जहां flag
वास्तव में एक उपयोगकर्ता-परिभाषित प्रकार है। फिर यह निर्भर करता है कि किस अधिभार का operator==
चयन किया गया है। बेशक यह मूर्खतापूर्ण लग सकता है कि वे सममित नहीं होंगे, लेकिन यह निश्चित रूप से अनुमत है, और मैंने पहले ही अन्य गालियां देखी हैं।
यदि flag
एक अंतर्निर्मित है, तो दोनों को समान गति लेनी चाहिए।
से विकिपीडिया लेख पर x86
, मैं एक के लिए शर्त होगी Jxx
के लिए अनुदेश if
बयान: शायद एक JNZ
(कूद अगर नहीं शून्य) या कुछ बराबर।
मुझे संदेह है कि संकलक ऐसे स्पष्ट अनुकूलन को याद करता है, भले ही अनुकूलन बंद हो गया हो। यह उन चीजों का प्रकार है जिनके लिए पीपहोल ऑप्टिमाइज़ेशन के लिए डिज़ाइन किया गया है।
संपादित करें: फिर से ऊपर आ गया, तो चलो कुछ विधानसभा (LLVM 2.7 IR) जोड़ें
int regular(int c) {
if (c == 0) { return 0; }
return 1;
}
int yoda(int c) {
if (0 == c) { return 0; }
return 1;
}
define i32 @regular(i32 %c) nounwind readnone {
entry:
%not. = icmp ne i32 %c, 0 ; <i1> [#uses=1]
%.0 = zext i1 %not. to i32 ; <i32> [#uses=1]
ret i32 %.0
}
define i32 @yoda(i32 %c) nounwind readnone {
entry:
%not. = icmp ne i32 %c, 0 ; <i1> [#uses=1]
%.0 = zext i1 %not. to i32 ; <i32> [#uses=1]
ret i32 %.0
}
यहां तक कि अगर कोई आईआर पढ़ना नहीं जानता है, तो मुझे लगता है कि यह स्वयं व्याख्यात्मक है।
flag
पूर्णांक या मूल होना चाहिए। OTOH, flag
एक उपयोगकर्ता-परिभाषित प्रकार का एक चर नाम है, अपने आप में काफी गलत है, IMHO
#include
निर्देश के भी उपलब्ध है । सादगी के लिए, यह आम तौर पर के बराबर है int
, char
, bool
और पसंद है। सभी अन्य प्रकार, उपयोगकर्ता परिभाषित होने के लिए कहा जाता है कि वे मौजूद हैं, क्योंकि वे उन्हें घोषित कुछ उपयोगकर्ता के परिणाम हैं: typedef
, enum
, struct
, class
। उदाहरण के लिए, std::string
उपयोगकर्ता परिभाषित है, भले ही आप निश्चित रूप से इसे स्वयं परिभाषित नहीं करते हैं :)
GCC 4.1.2 के साथ amd64 के लिए समान कोड:
.loc 1 4 0 # int f = argc;
movl -20(%rbp), %eax
movl %eax, -4(%rbp)
.loc 1 6 0 # if( f == 0 ) {
cmpl $0, -4(%rbp)
jne .L2
.loc 1 7 0 # return 0;
movl $0, -36(%rbp)
jmp .L4
.loc 1 8 0 # }
.L2:
.loc 1 10 0 # if( 0 == f ) {
cmpl $0, -4(%rbp)
jne .L5
.loc 1 11 0 # return 1;
movl $1, -36(%rbp)
jmp .L4
.loc 1 12 0 # }
.L5:
.loc 1 14 0 # return 2;
movl $2, -36(%rbp)
.L4:
movl -36(%rbp), %eax
.loc 1 15 0 # }
leave
ret
आपके संस्करणों में कोई अंतर नहीं होगा।
मैं मान रहा हूं कि type
ध्वज का प्रकार उपयोगकर्ता-परिभाषित प्रकार नहीं है, बल्कि यह कुछ अंतर्निहित प्रकार है। एनम अपवाद है! । आप एनम का इलाज कर सकते हैं जैसे कि यह बिल्ट-इन है। वास्तव में, यह 'बिल्ट-इन प्रकारों में से एक है!
मामले में, यदि यह उपयोगकर्ता-परिभाषित प्रकार (को छोड़कर enum
) है, तो उत्तर पूरी तरह से इस बात पर निर्भर करता है कि आपने ऑपरेटर को कैसे अधिभारित किया है ==
। ध्यान दें कि आपको अपने ==
प्रत्येक संस्करण के लिए दो कार्यों को परिभाषित करके ओवरलोड करना है!
बिल्कुल कोई अंतर नहीं है।
आप असाइनमेंट / तुलना टाइपो के उन्मूलन का उल्लेख करके उस साक्षात्कार प्रश्न का उत्तर देने में अंक प्राप्त कर सकते हैं, हालांकि:
if (flag = 0) // typo here
{
// code never executes
}
if (0 = flag) // typo and syntactic error -> compiler complains
{
// ...
}
हालांकि यह सच है, जैसे कि पूर्व के मामले में एक सी-कंपाइलर चेतावनी देता है ( flag = 0
), PHP, पर्ल या जावास्क्रिप्ट या ऐसी कोई चेतावनी नहीं है <insert language here>
।
बिल्कुल अंतर गति-वार नहीं होगा। क्यों होना चाहिए?
x == 0
इसका उपयोग कर 0 == x
सकता है लेकिन एक सामान्य तुलना का उपयोग कर सकता है। मैंने कहा कि इसे मंदबुद्धि होना पड़ेगा।
virtual operator==(int)
?
अच्छी तरह से एक अंतर है जब झंडा एक उपयोगकर्ता परिभाषित प्रकार है
struct sInt
{
sInt( int i ) : wrappedInt(i)
{
std::cout << "ctor called" << std::endl;
}
operator int()
{
std::cout << "operator int()" << std::endl;
return wrappedInt;
}
bool operator==(int nComp)
{
std::cout << "bool operator==(int nComp)" << std::endl;
return (nComp == wrappedInt);
}
int wrappedInt;
};
int
_tmain(int argc, _TCHAR* argv[])
{
sInt s(0);
//in this case this will probably be faster
if ( 0 == s )
{
std::cout << "equal" << std::endl;
}
if ( s == 0 )
{
std::cout << "equal" << std::endl;
}
}
पहले मामले में (0 == s) रूपांतरण ऑपरेटर कहा जाता है और फिर लौटा परिणाम की तुलना 0. की जाती है। दूसरे मामले में == ऑपरेटर को कहा जाता है।
जब संदेह में यह बेंचमार्क और सच जानने के लिए।
वे गति के मामले में बिल्कुल समान होना चाहिए।
ध्यान दें कि कुछ लोग बराबरी की तुलना में बायीं ओर स्थिरांक का उपयोग करते हैं (तथाकथित "योडा सशर्त") उन सभी त्रुटियों से बचने के लिए जो आप =
(असाइनमेंट ==
तुलना ऑपरेटर) के बजाय लिखते हैं (असाइनमेंट ऑपरेटर); चूंकि शाब्दिक रूप से एक संकलन त्रुटि को ट्रिगर करता है, इस तरह की गलती से बचा जाता है।
if(flag=0) // <--- typo: = instead of ==; flag is now set to 0
{
// this is never executed
}
if(0=flag) // <--- compiler error, cannot assign value to literal
{
}
दूसरी ओर, ज्यादातर लोग "योदा सशर्त" अजीब-दिखने वाले और परेशान होते हैं, खासकर जब से वे त्रुटियों को रोकते हैं, उन्हें पर्याप्त संकलक चेतावनी का उपयोग करके भी देखा जा सकता है।
if(flag=0) // <--- warning: assignment in conditional expression
{
}
जैसा कि दूसरों ने कहा है, कोई अंतर नहीं है।
0
मूल्यांकन किया जाना है। flag
मूल्यांकन किया जाना है। इस प्रक्रिया में एक ही समय लगता है, कोई फर्क नहीं पड़ता कि वे किस पक्ष में हैं।
सही उत्तर होगा: वे दोनों समान गति वाले हैं।
यहाँ तक कि भाव if(flag==0)
और if(0==flag)
वर्णों की मात्रा समान है! यदि उनमें से एक के रूप में लिखा गया था if(flag== 0)
, तो संकलक के पास पार्स करने के लिए एक अतिरिक्त स्थान होगा, इसलिए आपके पास संकलन समय को इंगित करने का एक वैध कारण होगा।
लेकिन चूंकि ऐसी कोई बात नहीं है, इसलिए पूरी तरह से कोई कारण नहीं है कि किसी को दूसरे की तुलना में तेज होना चाहिए। यदि कोई कारण है, तो संकलक उत्पन्न कोड के लिए कुछ बहुत, बहुत अजीब चीजें कर रहा है ...
कौन सा उपवास निर्भर करता है = किस संस्करण का उपयोग कर रहे हैं। यहां एक स्निपेट दिया गया है जिसमें == के 2 संभावित कार्यान्वयन का उपयोग किया गया है, और इस पर निर्भर करता है कि आप x == 0 या 0 == x में से किसी एक को चुनना चाहते हैं या नहीं।
यदि आप अभी POD का उपयोग कर रहे हैं तो यह वास्तव में तब नहीं होना चाहिए जब यह गति की बात आती है।
#include <iostream>
using namespace std;
class x {
public:
bool operator==(int x) { cout << "hello\n"; return 0; }
friend bool operator==(int x, const x& a) { cout << "world\n"; return 0; }
};
int main()
{
x x1;
//int m = 0;
int k = (x1 == 0);
int j = (0 == x1);
}
खैर, मैं ओपी के लिए टिप्पणियों में पूरी तरह से सहमत हूं, व्यायाम के लिए:
यदि कंपाइलर पर्याप्त चालाक नहीं है (वास्तव में आपको इसका उपयोग नहीं करना चाहिए) या अनुकूलन अक्षम है, तो x == 0
एक मूल असेंबली jump if zero
इंस्ट्रक्शन को संकलित 0 == x
कर सकता है , जबकि संख्यात्मक मूल्यों की तुलना में अधिक सामान्य (और महंगा) हो सकता है।
फिर भी, मैं ऐसे बॉस के लिए काम नहीं करना चाहूंगा जो इन शब्दों में सोचता हो ...
निष्पादन की गति के संदर्भ में निश्चित रूप से कोई अंतर नहीं है। हालत को दोनों मामलों में एक ही तरीके से मूल्यांकन करने की आवश्यकता है।
मुझे लगता है कि सबसे अच्छा जवाब "यह किस भाषा में उदाहरण है"?
प्रश्न में भाषा निर्दिष्ट नहीं थी और यह 'C' और 'C ++' दोनों को टैग किया गया था। एक सटीक उत्तर के लिए अधिक जानकारी की आवश्यकता होती है।
यह एक घटिया प्रोग्रामिंग प्रश्न है, लेकिन यह कुटिल में एक अच्छा हो सकता है "चलो साक्षात्कारकर्ता को पर्याप्त रस्सी दें या तो खुद को लटका दें या एक पेड़ स्विंग का निर्माण करें" विभाग। इस प्रकार के प्रश्नों के साथ समस्या यह है कि वे आमतौर पर नीचे लिखे जाते हैं और साक्षात्कारकर्ता से साक्षात्कारकर्ता को सौंप दिए जाते हैं जब तक कि यह उन लोगों को नहीं मिलता है जो वास्तव में सभी कोणों से इसे नहीं समझते हैं।
सुझाए गए तरीकों का उपयोग करके दो सरल प्रोग्राम बनाएं।
कोड इकट्ठा करें। विधानसभा को देखो और आप न्याय कर सकते हैं, लेकिन मुझे संदेह है कि एक अंतर है!
इंटरव्यू पहले से कम हो रहे हैं।
बस एक तरफ के रूप में (मुझे वास्तव में लगता है कि कोई भी सभ्य संकलक इस प्रश्न को गलत बना देगा, क्योंकि यह इसे अनुकूलित करेगा) 0 == फ्लैग ओवर का उपयोग करके == 0 टाइपो को रोकता है जहां आप किसी एक को भूल जाते हैं (यानी यदि आप गलती से टाइप करते हैं झंडा = 0 यह संकलित करेगा, लेकिन 0 = झंडा नहीं होगा), जो मुझे लगता है कि एक गलती है जो हर किसी ने एक बिंदु या किसी अन्य पर बनाई है ...