2017-01-09 11 views
6

पर आधारित मान निर्धारित करने का सबसे तेज़ तरीका यदि आपके पास बूलियन b और एक int i है, तो दो उदाहरणों में से कौन सा बेहतर है?बूलियन सी ++

int x = i-1; 
if(!b)x--; 

या

int x; 
if(b)x = i-1;else x = i-2; 

दोनों उदाहरणों में अगर b सच x है i-1, बाकी xi-2 है। क्या आपको x को i-1 के रूप में घोषित करना चाहिए और b गलत है या आप दूसरे उदाहरण का उपयोग करना चाहिए?

+9

शाखा रहित संस्करण 'x = i - 2 + b;' –

+4

संभावना अधिक है कि यदि आप रिलीज में संकलित करते हैं, तो संकलक उसी कोड को आउटपुट करेगा – user

+1

आप क्यों पूछते हैं? माइक्रो अनुकूलन अपरिवर्तनीय हैं। –

उत्तर

10

मुझे आश्चर्य होगा अगर कंपेलरों ने दोनों संस्करणों को एक ही इष्टतम असेंबली में अनुकूलित नहीं किया है। इस माइक्रो-ऑप्टिमाइज़ेशन के साथ अपना समय बर्बाद न करें जबतक कि आप यह साबित नहीं कर सकते कि वे प्रोफाइलर का उपयोग करके महत्वपूर्ण हैं।

अपने प्रश्न का उत्तर देने के लिए: यह अप्रासंगिक है। gcc.godbolt.org पर -Ofast के साथ "जेनरेटेड असेंबली" तुलना यहां दी गई है।


volatile int state0; 
volatile void f0(volatile int i, volatile bool b) 
{ 
    int x; 
    if(b)x = i-1;else x = i-2; 
    state0 = x; 
} 

... संकलित हो जाता है ...

f0(int, bool):        # @f0(int, bool) 
     mov  dword ptr [rsp - 4], edi 
     mov  byte ptr [rsp - 5], sil 
     movzx eax, byte ptr [rsp - 5] 
     or  eax, -2 
     add  eax, dword ptr [rsp - 4] 
     mov  dword ptr [rip + state0], eax 
     ret 

volatile int state1; 
volatile void f1(volatile int i, volatile bool b) 
{ 
    int x = i-1; 
    if(!b)x--; 
    state1 = x; 
} 

... संकलित हो जाता है ...

f1(int, bool):        # @f1(int, bool) 
     mov  dword ptr [rsp - 4], edi 
     mov  byte ptr [rsp - 5], sil 
     mov  eax, dword ptr [rsp - 4] 
     movzx ecx, byte ptr [rsp - 5] 
     or  ecx, -2 
     add  ecx, eax 
     mov  dword ptr [rip + state1], ecx 
     ret 

जैसा कि आप देख सकते हैं, अंतर कम है, और volatile को हटाकर संकलक को अधिक आक्रामक रूप से अनुकूलित करने की अनुमति देने पर अत्यधिक गायब होने की संभावना है।


यहाँ चित्र के रूप में एक समान तुलना, -Ofast -march=native -ffast-math का उपयोग कर रहा है:

Godbolt comparison

+0

कृपया बताएं कि आपने कौन से झंडे का उपयोग किया है (-O3?) –

+0

@IvanRubinson: यह गॉडबॉल्ट लिंक पर है, मैंने' -Ofast' 'का उपयोग किया था। –

+0

धन्यवाद!मैं सिर्फ इसलिए पूछ रहा था क्योंकि मैं उत्सुक था। – theo2003

5

, विधानसभा कोड की जाँच करें क्योंकि अनुकूलक संभवतः, अनुकूलित करेंगे ही समाधान करने के लिए अपने दोनों समाधान।

शायद मैं इसे लागू करेगा के रूप में:

int x = (b) ? i - 1 : i - 2; 

पठनीयता और उच्च संभावना अनुकूलक यह अपने दूसरे समाधान के रूप में बराबर कर देगा के लिए।

+3

मैं 'int x = i-b लिखूंगा? 1: 2; 'i'' का उल्लेख नहीं करना – Slava

+1

मैं 'const int x = i - 2 + !! b' लिखूंगा ताकि कोई भी शाखा न हो। –

+0

'int x = i - 2 + b' काम करेगा? – theo2003

संबंधित मुद्दे