क्या आपको लगता है कि उनमें से किसी एक भी लाइनर तेज या धीमी है?
unsigned int fun0 ( unsigned int condition, unsigned int value )
{
value = 5;
if (condition) {
value = 6;
}
return(value);
}
unsigned int fun1 ( unsigned int condition, unsigned int value )
{
if (condition) {
value = 6;
} else {
value = 5;
}
return(value);
}
unsigned int fun2 ( unsigned int condition, unsigned int value )
{
value = condition ? 6 : 5;
return(value);
}
एक उच्च स्तरीय भाषा के कोड की अधिक पंक्तियाँ कंपाइलर को काम करने के लिए अधिक प्रदान करती हैं, यदि आप एक सामान्य नियम बनाना चाहते हैं तो इसके बारे में कंपाइलर को अधिक कोड के साथ काम करने दें। यदि एल्गोरिथ्म ऊपर के मामलों की तरह ही है, तो एक कंपाइलर से अपेक्षा की जाएगी कि वह कम से कम अनुकूलन के साथ यह पता लगाए।
00000000 <fun0>:
0: e3500000 cmp r0, #0
4: 03a00005 moveq r0, #5
8: 13a00006 movne r0, #6
c: e12fff1e bx lr
00000010 <fun1>:
10: e3500000 cmp r0, #0
14: 13a00006 movne r0, #6
18: 03a00005 moveq r0, #5
1c: e12fff1e bx lr
00000020 <fun2>:
20: e3500000 cmp r0, #0
24: 13a00006 movne r0, #6
28: 03a00005 moveq r0, #5
2c: e12fff1e bx lr
एक बड़ा आश्चर्य नहीं है कि यह एक अलग क्रम में पहला कार्य किया, एक ही निष्पादन समय हालांकि।
0000000000000000 <fun0>:
0: 7100001f cmp w0, #0x0
4: 1a9f07e0 cset w0, ne
8: 11001400 add w0, w0, #0x5
c: d65f03c0 ret
0000000000000010 <fun1>:
10: 7100001f cmp w0, #0x0
14: 1a9f07e0 cset w0, ne
18: 11001400 add w0, w0, #0x5
1c: d65f03c0 ret
0000000000000020 <fun2>:
20: 7100001f cmp w0, #0x0
24: 1a9f07e0 cset w0, ne
28: 11001400 add w0, w0, #0x5
2c: d65f03c0 ret
उम्मीद है कि आपको यह अंदाजा हो सकता है कि आपने अभी यह कोशिश की होगी कि यह स्पष्ट न हो कि विभिन्न कार्यान्वयन वास्तव में अलग नहीं थे।
जहां तक मैट्रिक्स जाता है, यकीन नहीं होता कि कैसे मायने रखता है,
if(condition)
{
big blob of code a
}
else
{
big blob of code b
}
कोड के बड़े ब्लब्स के चारों ओर एक ही अगर-फिर-अन्यथा आवरण डालने जा रहे हैं तो उनका मूल्य = 5 या कुछ अधिक जटिल हो सकता है। इसी तरह से तुलना करें, भले ही यह कोड की एक बड़ी बूँद है, जिसे अभी भी गणना करना है, और इसके बराबर या कुछ के बराबर नहीं है अक्सर नकारात्मक के साथ संकलित किया जाता है, अगर (स्थिति) कुछ ऐसा अक्सर संकलित किया जाता है जैसे कि हालत गोटो नहीं।
00000000 <fun0>:
0: 0f 93 tst r15
2: 03 24 jz $+8 ;abs 0xa
4: 3f 40 06 00 mov #6, r15 ;#0x0006
8: 30 41 ret
a: 3f 40 05 00 mov #5, r15 ;#0x0005
e: 30 41 ret
00000010 <fun1>:
10: 0f 93 tst r15
12: 03 20 jnz $+8 ;abs 0x1a
14: 3f 40 05 00 mov #5, r15 ;#0x0005
18: 30 41 ret
1a: 3f 40 06 00 mov #6, r15 ;#0x0006
1e: 30 41 ret
00000020 <fun2>:
20: 0f 93 tst r15
22: 03 20 jnz $+8 ;abs 0x2a
24: 3f 40 05 00 mov #5, r15 ;#0x0005
28: 30 41 ret
2a: 3f 40 06 00 mov #6, r15 ;#0x0006
2e: 30 41
हम अभी हाल ही में स्टैकओवरफ्लो पर किसी और के साथ इस अभ्यास से गुजरे। इस मामले में यह mips संकलक दिलचस्प है कि न केवल एहसास ही कार्य समान थे, लेकिन एक फ़ंक्शन कोड स्थान को बचाने के लिए बस दूसरे पर कूद गया था। हालांकि यहाँ ऐसा नहीं किया
00000000 <fun0>:
0: 0004102b sltu $2,$0,$4
4: 03e00008 jr $31
8: 24420005 addiu $2,$2,5
0000000c <fun1>:
c: 0004102b sltu $2,$0,$4
10: 03e00008 jr $31
14: 24420005 addiu $2,$2,5
00000018 <fun2>:
18: 0004102b sltu $2,$0,$4
1c: 03e00008 jr $31
20: 24420005 addiu $2,$2,5
कुछ और लक्ष्य।
00000000 <_fun0>:
0: 1166 mov r5, -(sp)
2: 1185 mov sp, r5
4: 0bf5 0004 tst 4(r5)
8: 0304 beq 12 <_fun0+0x12>
a: 15c0 0006 mov $6, r0
e: 1585 mov (sp)+, r5
10: 0087 rts pc
12: 15c0 0005 mov $5, r0
16: 1585 mov (sp)+, r5
18: 0087 rts pc
0000001a <_fun1>:
1a: 1166 mov r5, -(sp)
1c: 1185 mov sp, r5
1e: 0bf5 0004 tst 4(r5)
22: 0204 bne 2c <_fun1+0x12>
24: 15c0 0005 mov $5, r0
28: 1585 mov (sp)+, r5
2a: 0087 rts pc
2c: 15c0 0006 mov $6, r0
30: 1585 mov (sp)+, r5
32: 0087 rts pc
00000034 <_fun2>:
34: 1166 mov r5, -(sp)
36: 1185 mov sp, r5
38: 0bf5 0004 tst 4(r5)
3c: 0204 bne 46 <_fun2+0x12>
3e: 15c0 0005 mov $5, r0
42: 1585 mov (sp)+, r5
44: 0087 rts pc
46: 15c0 0006 mov $6, r0
4a: 1585 mov (sp)+, r5
4c: 0087 rts pc
00000000 <fun0>:
0: 00a03533 snez x10,x10
4: 0515 addi x10,x10,5
6: 8082 ret
00000008 <fun1>:
8: 00a03533 snez x10,x10
c: 0515 addi x10,x10,5
e: 8082 ret
00000010 <fun2>:
10: 00a03533 snez x10,x10
14: 0515 addi x10,x10,5
16: 8082 ret
और संकलक
इस i कोड के साथ एक ही मैच के लिए विभिन्न लक्ष्यों की उम्मीद होगी
define i32 @fun0(i32 %condition, i32 %value) #0 {
%1 = icmp ne i32 %condition, 0
%. = select i1 %1, i32 6, i32 5
ret i32 %.
}
; Function Attrs: norecurse nounwind readnone
define i32 @fun1(i32 %condition, i32 %value) #0 {
%1 = icmp eq i32 %condition, 0
%. = select i1 %1, i32 5, i32 6
ret i32 %.
}
; Function Attrs: norecurse nounwind readnone
define i32 @fun2(i32 %condition, i32 %value) #0 {
%1 = icmp ne i32 %condition, 0
%2 = select i1 %1, i32 6, i32 5
ret i32 %2
}
00000000 <fun0>:
0: e3a01005 mov r1, #5
4: e3500000 cmp r0, #0
8: 13a01006 movne r1, #6
c: e1a00001 mov r0, r1
10: e12fff1e bx lr
00000014 <fun1>:
14: e3a01006 mov r1, #6
18: e3500000 cmp r0, #0
1c: 03a01005 moveq r1, #5
20: e1a00001 mov r0, r1
24: e12fff1e bx lr
00000028 <fun2>:
28: e3a01005 mov r1, #5
2c: e3500000 cmp r0, #0
30: 13a01006 movne r1, #6
34: e1a00001 mov r0, r1
38: e12fff1e bx lr
fun0:
push.w r4
mov.w r1, r4
mov.w r15, r12
mov.w #6, r15
cmp.w #0, r12
jne .LBB0_2
mov.w #5, r15
.LBB0_2:
pop.w r4
ret
fun1:
push.w r4
mov.w r1, r4
mov.w r15, r12
mov.w #5, r15
cmp.w #0, r12
jeq .LBB1_2
mov.w #6, r15
.LBB1_2:
pop.w r4
ret
fun2:
push.w r4
mov.w r1, r4
mov.w r15, r12
mov.w #6, r15
cmp.w #0, r12
jne .LBB2_2
mov.w #5, r15
.LBB2_2:
pop.w r4
ret
अब तकनीकी रूप से इनमें से कुछ समाधानों में एक प्रदर्शन अंतर है, कभी-कभी परिणाम 5 होता है, परिणाम पर एक छलांग होती है 6 कोड, और इसके विपरीत, एक शाखा है जिसके माध्यम से निष्पादित करने की तुलना में तेज है? कोई बहस कर सकता है लेकिन अमल अलग-अलग होना चाहिए। लेकिन अगर कोड में हालत नहीं है, तो यह अधिक है, यदि कंपाइलर के परिणामस्वरूप कोड में स्थिति होती है, तो यदि यह कूदता है तो इसके माध्यम से निष्पादित होता है। लेकिन यह जरूरी नहीं कि कोडिंग शैली के कारण हो, लेकिन तुलना और अगर और जो कुछ भी वाक्यविन्यास में है, उसकी तुलना।