ซึ่งเร็วกว่า: if (bool) หรือ if (int)?


94

ใช้คุ้มค่าไหนดี? บูลีนจริงหรือจำนวนเต็ม 1?

หัวข้อดังกล่าวข้างต้นทำให้ผมทำการทดลองบางคนที่มีboolและintในifสภาพ ดังนั้นฉันจึงเขียนโปรแกรมนี้ด้วยความอยากรู้อยากเห็น:

int f(int i) 
{
    if ( i ) return 99;   //if(int)
    else  return -99;
}
int g(bool b)
{
    if ( b ) return 99;   //if(bool)
    else  return -99;
}
int main(){}

g++ intbool.cpp -S สร้างรหัส asm สำหรับแต่ละฟังก์ชันดังนี้:

  • รหัส asm สำหรับ f(int)

    __Z1fi:
       LFB0:
             pushl  %ebp
       LCFI0:
              movl  %esp, %ebp
       LCFI1:
              cmpl  $0, 8(%ebp)
              je    L2
              movl  $99, %eax
              jmp   L3
       L2:
              movl  $-99, %eax
       L3:
              leave
       LCFI2:
              ret
    
  • รหัส asm สำหรับ g(bool)

    __Z1gb:
       LFB1:
              pushl %ebp
       LCFI3:
              movl  %esp, %ebp
       LCFI4:
              subl  $4, %esp
       LCFI5:
              movl  8(%ebp), %eax
              movb  %al, -4(%ebp)
              cmpb  $0, -4(%ebp)
              je    L5
              movl  $99, %eax
              jmp   L6
       L5:
              movl  $-99, %eax
       L6:
              leave
       LCFI6:
              ret
    

น่าแปลกใจที่g(bool)สร้างasmคำแนะนำเพิ่มเติม! หมายความว่าif(bool)ช้ากว่าเล็กน้อยif(int)? ฉันเคยคิดว่าboolถูกออกแบบมาโดยเฉพาะเพื่อใช้ในคำสั่งเงื่อนไขเช่นifดังนั้นฉันจึงคาดหวังว่าg(bool)จะสร้างคำสั่ง asm น้อยลงจึงทำให้g(bool)มีประสิทธิภาพและรวดเร็วมากขึ้น

แก้ไข:

ฉันไม่ได้ใช้ค่าสถานะการเพิ่มประสิทธิภาพใด ๆ ณ ตอนนี้ แต่ถึงจะไม่มีมันทำไมมันถึงสร้าง asm ให้มากขึ้นg(bool)เป็นคำถามที่ฉันกำลังมองหาคำตอบที่สมเหตุสมผล ฉันควรบอกคุณด้วยว่า-O2แฟล็กการเพิ่มประสิทธิภาพสร้าง asm เหมือนกันทุกประการ แต่นั่นไม่ใช่คำถาม คำถามคือสิ่งที่ฉันเคยถาม



32
นอกจากนี้ยังเป็นการทดสอบที่ไม่ยุติธรรมเว้นแต่คุณจะเปรียบเทียบกับการเพิ่มประสิทธิภาพที่เหมาะสม
Daniel Pryden

9
@ แดเนียล: ฉันไม่ได้ใช้แฟล็กการเพิ่มประสิทธิภาพกับแฟล็กใดแฟล็กใดเลย แต่ถึงจะไม่มีมันทำไมมันถึงสร้าง asm ให้มากขึ้นg(bool)เป็นคำถามที่ฉันกำลังมองหาคำตอบที่สมเหตุสมผล
Nawaz

8
ทำไมคุณจะไปที่ปัญหาของการอ่าน asm ที่แต่ไม่ได้เป็นเพียงการเรียกใช้โปรแกรมและเวลาผล ? จำนวนอาจารย์ไม่ได้พูดถึงประสิทธิภาพมากนัก คุณต้องแยกตัวประกอบไม่เพียงแค่ความยาวของคำสั่งเท่านั้น แต่ยังรวมถึงการอ้างอิงและประเภทของคำสั่งด้วย (มีบางตัวที่ถอดรหัสโดยใช้เส้นทางไมโครโค้ดที่ช้ากว่าซึ่งหน่วยประมวลผลที่พวกเขาต้องการความหน่วงแฝงและปริมาณงานของคำสั่งคืออะไร สาขา? A memmory access?
jalf

2
@ ไม่รู้จักผู้ใช้และ @Malvolio: เห็นได้ชัดว่า; ฉันไม่ได้ทำสิ่งเหล่านี้สำหรับรหัสการผลิต ที่ผมกล่าวถึงแล้วในจุดเริ่มต้นของการโพสต์ของฉันว่า"ดังนั้นเพียงแค่ออกจากความอยากรู้ผมเขียนโปรแกรมนี้" เพื่อใช่เป็นของมันอย่างหมดจดสมมุติหนึ่ง
Nawaz

3
เป็นคำถามที่ถูกต้อง พวกมันเทียบเท่าหรือเร็วกว่า ASM อาจถูกโพสต์ด้วยความพยายามที่จะเป็นประโยชน์หรือคิดออกมาดัง ๆ ดังนั้นแทนที่จะใช้เป็นวิธีหลบคำถามและพูดว่า "เขียนโค้ดที่อ่านได้" เพียงตอบคำถามหรือ STFU หากคุณไม่รู้หรือ ไม่มีประโยชน์อะไรที่จะพูด;) การมีส่วนร่วมของฉันคือคำถามนั้นสามารถตอบได้และ "เพียงแค่เขียนโค้ดที่อ่านได้" ก็ไม่มีอะไรนอกจากการหลบเลี่ยงคำถาม
Triynko

คำตอบ:


99

ทำให้รู้สึกดีกับฉัน เห็นได้ชัดว่าคอมไพเลอร์ของคุณกำหนดboolเป็นค่า 8 บิตและระบบของคุณ ABI กำหนดให้ "เลื่อน" อาร์กิวเมนต์จำนวนเต็มขนาดเล็ก (<32 บิต) เป็น 32 บิตเมื่อผลักดันไปยัง call stack ดังนั้นเพื่อเปรียบเทียบboolคอมไพเลอร์สร้างรหัสเพื่อแยกไบต์ที่สำคัญน้อยที่สุดของอาร์กิวเมนต์ 32 cmpbบิตที่ได้รับกรัมและเปรียบเทียบกับ ในตัวอย่างแรกที่intอาร์กิวเมนต์ใช้เต็มรูปแบบ 32 cmplบิตที่ถูกผลักลงบนสแต็คดังนั้นมันก็เปรียบเทียบกับสิ่งที่ทั้งกับ


4
ฉันเห็นด้วย. สิ่งนี้ช่วยให้ความกระจ่างว่าเมื่อเลือกประเภทตัวแปรคุณกำลังเลือกเพื่อวัตถุประสงค์สองประการที่อาจแข่งขันกันพื้นที่จัดเก็บเทียบกับประสิทธิภาพการคำนวณ
Triynko

3
สิ่งนี้ใช้กับกระบวนการ 64 บิตซึ่ง__int64เร็วกว่าintหรือไม่ หรือ CPU จัดการจำนวนเต็ม 32 บิตกับชุดคำสั่ง 32 บิตแยกกัน?
Crend King

1
@CrendKing อาจจะคุ้มค่าที่จะตอบคำถามอื่น?
ชื่อที่แสดง

81

การรวบรวม-03จะให้สิ่งต่อไปนี้สำหรับฉัน:

ฉ:

    pushl   %ebp
    movl    %esp, %ebp
    cmpl    $1, 8(%ebp)
    popl    %ebp
    sbbl    %eax, %eax
    andb    $58, %al
    addl    $99, %eax
    ret

g:

    pushl   %ebp
    movl    %esp, %ebp
    cmpb    $1, 8(%ebp)
    popl    %ebp
    sbbl    %eax, %eax
    andb    $58, %al
    addl    $99, %eax
    ret

.. ดังนั้นจึงรวบรวมเป็นหลักรหัสเดียวกันยกเว้นVScmpl cmpbนั่นหมายความว่าความแตกต่างถ้ามีก็ไม่สำคัญ การตัดสินโดยรหัสที่ไม่ได้เพิ่มประสิทธิภาพนั้นไม่ยุติธรรม


แก้ไขเพื่อชี้แจงประเด็นของฉัน รหัสที่ไม่ได้เพิ่มประสิทธิภาพมีไว้สำหรับการดีบักอย่างง่ายไม่ใช่เพื่อความเร็ว การเปรียบเทียบความเร็วของโค้ดที่ไม่ได้เพิ่มประสิทธิภาพนั้นไม่สมเหตุสมผล


8
เท่าที่ฉันเห็นด้วยกับข้อสรุปของคุณฉันคิดว่าคุณกำลังข้ามส่วนที่น่าสนใจ ทำไมจึงใช้cmplสำหรับหนึ่งและcmpbอื่น ๆ ?
ม.ค.

22
@jalf: เนื่องจาก a boolเป็นไบต์เดียวและintเป็นสี่ ฉันไม่คิดว่าจะมีอะไรพิเศษไปกว่านั้น
CB Bailey

7
ฉันคิดว่าคำตอบอื่น ๆ ให้ความสำคัญกับเหตุผลมากกว่านั่นเป็นเพราะแพลตฟอร์มที่มีปัญหาถือว่าboolเป็นประเภท 8 บิต
Alexander Gessler

9
@Nathan: ไม่ C ++ ไม่มีชนิดข้อมูลบิต ประเภทที่เล็กที่สุดคือcharซึ่งเป็นไบต์ตามนิยามและเป็นหน่วยแอดเดรสที่เล็กที่สุด boolขนาดของการนำไปใช้งานกำหนดไว้และอาจเป็น 1, 4 หรือ 8 หรืออะไรก็ได้ แม้ว่าคอมไพเลอร์มักจะทำให้เป็นหนึ่งเดียว
GManNickG

6
@ นาธาน: ก็เป็นเรื่องยากใน Java เช่นกัน Java กล่าวว่าข้อมูลที่บูลีนแสดงถึงเป็นค่าหนึ่งบิต แต่วิธีการจัดเก็บบิตนั้นยังคงมีการกำหนดการใช้งานอยู่ คอมพิวเตอร์ในทางปฏิบัติไม่ได้ระบุบิต
GManNickG

26

เมื่อฉันรวบรวมสิ่งนี้ด้วยชุดตัวเลือกที่มีเหตุผล (โดยเฉพาะ -O3) นี่คือสิ่งที่ฉันได้รับ:

สำหรับf():

        .type   _Z1fi, @function
_Z1fi:
.LFB0:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        cmpl    $1, %edi
        sbbl    %eax, %eax
        andb    $58, %al
        addl    $99, %eax
        ret
        .cfi_endproc

สำหรับg():

        .type   _Z1gb, @function
_Z1gb:
.LFB1:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        cmpb    $1, %dil
        sbbl    %eax, %eax
        andb    $58, %al
        addl    $99, %eax
        ret
        .cfi_endproc

พวกเขายังคงใช้คำแนะนำที่แตกต่างกันสำหรับการเปรียบเทียบ ( cmpbสำหรับบูลีนเทียบกับcmplสำหรับ int) แต่อย่างอื่นร่างกายจะเหมือนกัน การดูคู่มือของ Intel อย่างรวดเร็วช่วยบอกฉันว่า: ... ไม่มีอะไรมาก ไม่มีสิ่งที่เรียกว่าcmpbหรือcmplในคู่มือของ Intel พวกเขาทั้งหมดcmpและฉันไม่พบตารางเวลาในขณะนี้ อย่างไรก็ตามฉันคาดเดาว่าไม่มีความแตกต่างของนาฬิการะหว่างการเปรียบเทียบไบต์ทันทีกับการเปรียบเทียบแบบยาวทันทีดังนั้นสำหรับวัตถุประสงค์ในทางปฏิบัติทั้งหมดรหัสจะเหมือนกัน


แก้ไขเพื่อเพิ่มสิ่งต่อไปนี้ตามการเพิ่มของคุณ

สาเหตุที่รหัสแตกต่างกันในกรณีที่ไม่ได้เพิ่มประสิทธิภาพคือรหัสไม่ได้รับการเพิ่มประสิทธิภาพ (ใช่มันเป็นวงกลมฉันรู้) เมื่อคอมไพเลอร์เดินตาม AST และสร้างโค้ดโดยตรงมันจะไม่ "รู้" อะไรเลยนอกจากว่ามีอะไรอยู่ที่จุด AST ในทันที ณ จุดนั้นมันขาดข้อมูลเชิงบริบททั้งหมดที่จำเป็น เพื่อให้ทราบว่า ณ จุดที่เฉพาะเจาะจงนี้สามารถถือว่าประเภทที่ประกาศboolเป็นintไฟล์. โดยค่าเริ่มต้นบูลีนจะถือว่าเป็นไบต์และเมื่อจัดการกับไบต์ในโลกของ Intel คุณต้องทำสิ่งต่าง ๆ เช่น sign-expand เพื่อนำไปยังความกว้างที่กำหนดเพื่อวางลงบนสแต็กเป็นต้น (คุณไม่สามารถพุชไบต์ .)

อย่างไรก็ตามเมื่อเครื่องมือเพิ่มประสิทธิภาพดู AST และใช้เวทมนตร์มันจะดูบริบทโดยรอบและ "รู้" เมื่อสามารถแทนที่โค้ดด้วยสิ่งที่มีประสิทธิภาพมากขึ้นโดยไม่ต้องเปลี่ยนความหมาย ดังนั้นจึง "รู้" ว่าสามารถใช้จำนวนเต็มในพารามิเตอร์และทำให้สูญเสียการแปลงที่ไม่จำเป็นและการขยับขยาย


1
ฮ่า ๆ ฉันชอบวิธีที่คอมไพเลอร์ส่งคืน 99 หรือ 99 + 58 = 157 = -99 (ล้นของ 8 บิตที่ลงชื่อ) ... น่าสนใจ
deceleratedcaviar

@ แดเนียล: แม้ว่าฉันจะชอบสิ่งนั้น ตอนแรกฉันพูดว่า "ที่ไหนคือ -99" และทันทีที่ฉันรู้ว่ามันทำอะไรแปลก ๆ มาก
Nawaz

7
lและbเป็นคำต่อท้ายที่ใช้ในไวยากรณ์ AT&T เท่านั้น พวกเขาอ้างถึงเวอร์ชันของการcmpใช้ตัวถูกดำเนินการ 4 ไบต์ (ยาว) และ 1 ไบต์ (ไบต์) ตามลำดับ ในกรณีที่มีความเคลือบแคลงใด ๆ ในไวยากรณ์ Intel, อัตภาพถูกดำเนินการของหน่วยความจำที่มีการติดแท็กด้วยBYTE PTR, WORD PTRหรือDWORD PTRแทนการใส่ต่อท้ายใน opcode
CB Bailey

ตารางเวลา: agner.org/optimize ทั้งสองตัวถูกดำเนินการขนาดของcmpมีประสิทธิภาพการทำงานที่เหมือนกันและไม่มีการลงโทษบางส่วนลงทะเบียนสำหรับการอ่าน %dil(แต่นั่นไม่ได้หยุดเสียงดังจากการสร้างแผงขายสินค้าบางส่วนอย่างขบขันโดยใช้ขนาดไบต์andบน AL เป็นส่วนหนึ่งของการพลิกกรณีแบบไม่มีสาขาระหว่าง 99 ถึง -99)
ปีเตอร์คอร์เดส

13

ด้วย GCC 4.5 บน Linux และ Windows เป็นอย่างน้อย, sizeof(bool) == 1. บน x86 และ x86_64 คุณไม่สามารถส่งผ่านค่ารีจิสเตอร์วัตถุประสงค์ทั่วไปไปยังฟังก์ชันได้น้อยกว่า (ไม่ว่าจะผ่านสแต็กหรือรีจิสเตอร์ขึ้นอยู่กับรูปแบบการโทร ฯลฯ ... )

ดังนั้นโค้ดสำหรับ bool เมื่อไม่ได้รับการปรับให้เหมาะสมจะมีความยาวเพื่อแยกค่าบูลนั้นออกจากกองอาร์กิวเมนต์ (โดยใช้ช่องสแต็กอื่นเพื่อบันทึกไบต์นั้น) มันซับซ้อนกว่าแค่ดึงตัวแปรขนาดรีจิสเตอร์ดั้งเดิม


จากมาตรฐาน C ++ 03, §5.3.3 / 1: " sizeof(bool)และsizeof(wchar_t)มีการกำหนดการนำไปใช้งาน " ดังนั้นการพูดsizeof(bool) == 1จึงไม่ถูกต้องอย่างเคร่งครัดเว้นแต่คุณจะพูดถึงเวอร์ชันเฉพาะของคอมไพเลอร์เฉพาะ
ildjarn

9

ที่ระดับเครื่องจะไม่มีบูล

สถาปัตยกรรมชุดคำสั่งน้อยมากที่กำหนดประเภทตัวถูกดำเนินการบูลีนประเภทใดก็ได้แม้ว่ามักจะมีคำสั่งที่ทริกเกอร์การดำเนินการกับค่าที่ไม่ใช่ศูนย์ สำหรับซีพียูโดยทั่วไปทุกอย่างเป็นประเภทสเกลาร์หรือสตริงของพวกเขา

คอมไพเลอร์ที่กำหนดและ ABI ที่กำหนดจะต้องเลือกขนาดเฉพาะสำหรับ intและboolและเมื่อเช่นในกรณีของคุณซึ่งเป็นขนาดที่แตกต่างกันซึ่งอาจสร้างโค้ดที่แตกต่างกันเล็กน้อยและในบางระดับของการเพิ่มประสิทธิภาพอาจเร็วกว่าเล็กน้อย

เหตุใดบูลหนึ่งไบต์ในหลายระบบ

การเลือกcharประเภทของบูลจะปลอดภัยกว่าเนื่องจากอาจมีคนสร้างอาร์เรย์จำนวนมาก

อัปเดต:โดย"ปลอดภัยกว่า"ฉันหมายถึง: สำหรับผู้ใช้คอมไพเลอร์และไลบรารี ฉันไม่ได้บอกว่าคนอื่นต้องติดตั้งระบบประเภทนี้ใหม่


2
+1 ลองนึกภาพค่าโสหุ้ยบน x86 ถ้าboolแทนด้วยบิต ดังนั้นไบต์จะเป็นการแลกเปลี่ยนที่ดีสำหรับความเร็ว / ความกะทัดรัดของข้อมูลในการใช้งานจำนวนมาก
hardmath

1
@ บิลลี่: ฉันคิดว่าเขาไม่ได้พูดว่า "ใช้charแทนbool" แต่ใช้เพียง " charพิมพ์" แทนเพื่อหมายถึง "1 ไบต์" เมื่ออ้างถึงขนาดที่คอมไพเลอร์เลือกสำหรับboolอ็อบเจ็กต์
Dennis Zickefoose

โอ้ฉันไม่ได้หมายความว่าแต่ละโปรแกรมควรเลือกฉันแค่กำลังพัฒนาเหตุผลว่าทำไมประเภทบูลของระบบเป็น 1 ไบต์
DigitalRoss

@ เดนนิส: อ่ามันสมเหตุสมผลแล้ว
Billy ONeal

7

ใช่การอภิปรายเป็นเรื่องสนุก แต่เพียงทดสอบ:

รหัสทดสอบ:

#include <stdio.h>
#include <string.h>

int testi(int);
int testb(bool);
int main (int argc, char* argv[]){
  bool valb;
  int  vali;
  int loops;
  if( argc < 2 ){
    return 2;
  }
  valb = (0 != (strcmp(argv[1], "0")));
  vali = strcmp(argv[1], "0");
  printf("Arg1: %s\n", argv[1]);
  printf("BArg1: %i\n", valb ? 1 : 0);
  printf("IArg1: %i\n", vali);
  for(loops=30000000; loops>0; loops--){
    //printf("%i: %i\n", loops, testb(valb=!valb));
    printf("%i: %i\n", loops, testi(vali=!vali));
  }
  return valb;
}

int testi(int val){
  if( val ){
    return 1;
  }
  return 0;
}
int testb(bool val){
  if( val ){
    return 1;
  }
  return 0;
}

คอมไพล์บนแล็ปท็อป Ubuntu 10.10 64 บิตพร้อมด้วย: g ++ -O3 -o / tmp / test_i /tmp/test_i.cpp

การเปรียบเทียบตามจำนวนเต็ม:

sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m8.203s
user    0m8.170s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m8.056s
user    0m8.020s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m8.116s
user    0m8.100s
sys 0m0.000s

การทดสอบบูลีน / การพิมพ์ที่ไม่มีการแสดงความคิดเห็น (และจำนวนเต็มแสดงความคิดเห็น):

sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m8.254s
user    0m8.240s
sys 0m0.000s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m8.028s
user    0m8.000s
sys 0m0.010s
sauer@trogdor:/tmp$ time /tmp/test_i 1 > /dev/null

real    0m7.981s
user    0m7.900s
sys 0m0.050s

เหมือนกันกับงาน 1 ชิ้นและการเปรียบเทียบ 2 ครั้งในแต่ละลูปมากกว่า 30 ล้านลูป ค้นหาสิ่งอื่นเพื่อเพิ่มประสิทธิภาพ ตัวอย่างเช่นอย่าใช้ strcmp โดยไม่จำเป็น ;)


2

ส่วนใหญ่จะขึ้นอยู่กับคอมไพเลอร์และการปรับให้เหมาะสม มีการสนทนาที่น่าสนใจ (ไม่เชื่อเรื่องพระเจ้าภาษา) ที่นี่:

"if ([bool] == true)" ต้องการมากกว่าหนึ่งขั้นตอนกว่า "if ([bool])" หรือไม่

ดูที่โพสต์นี้: http://www.linuxquestions.org/questions/programming-9/c-compiler-handling-of-boolean-variables-290996/


0

เข้าหาคำถามของคุณด้วยสองวิธีที่แตกต่างกัน:

หากคุณกำลังพูดถึง C ++ โดยเฉพาะหรือภาษาโปรแกรมใด ๆ ที่จะสร้างรหัสแอสเซมบลีสำหรับเรื่องนั้นเราจะผูกพันกับโค้ดที่คอมไพเลอร์จะสร้างใน ASM นอกจากนี้เรายังผูกพันกับการแทนค่าจริงและเท็จใน c ++ จำนวนเต็มจะต้องถูกเก็บเป็น 32 บิตและฉันสามารถใช้ไบต์เพื่อเก็บนิพจน์บูลีนได้ ข้อมูลโค้ด Asm สำหรับคำสั่งเงื่อนไข:

สำหรับจำนวนเต็ม:

  mov eax,dword ptr[esp]    ;Store integer
  cmp eax,0                 ;Compare to 0
  je  false                 ;If int is 0, its false
  ;Do what has to be done when true
false:
  ;Do what has to be done when false

สำหรับบูล:

  mov  al,1     ;Anything that is not 0 is true
  test al,1     ;See if first bit is fliped
  jz   false    ;Not fliped, so it's false
  ;Do what has to be done when true
false:
  ;Do what has to be done when false

นั่นเป็นเหตุผลว่าทำไมการเปรียบเทียบความเร็วจึงขึ้นอยู่กับการคอมไพล์ ในกรณีข้างต้นบูลจะเร็วขึ้นเล็กน้อยตั้งแต่นั้นมาcmpจะบ่งบอกถึงการลบสำหรับการตั้งค่าแฟล็ก นอกจากนี้ยังขัดแย้งกับสิ่งที่คอมไพเลอร์ของคุณสร้างขึ้น

อีกวิธีหนึ่งที่ง่ายกว่ามากคือดูตรรกะของนิพจน์ด้วยตัวมันเองและพยายามอย่ากังวลว่าคอมไพเลอร์จะแปลโค้ดของคุณอย่างไรและฉันคิดว่านี่เป็นวิธีคิดที่ดีต่อสุขภาพกว่ามาก ในที่สุดฉันก็ยังเชื่อว่าโค้ดที่คอมไพเลอร์สร้างขึ้นนั้นพยายามที่จะให้การแก้ปัญหาที่เป็นจริง สิ่งที่ฉันหมายถึงคือบางทีถ้าคุณเพิ่มกรณีทดสอบในคำสั่ง if และยึดติดกับบูลีนในด้านหนึ่งและจำนวนเต็มในอีกด้านหนึ่งคอมไพเลอร์จะสร้างมันขึ้นมาเพื่อให้โค้ดที่สร้างขึ้นจะทำงานได้เร็วขึ้นด้วยนิพจน์บูลีนในระดับเครื่อง

ฉันกำลังพิจารณาว่านี่เป็นคำถามเชิงแนวคิดดังนั้นฉันจะให้คำตอบตามแนวคิด การสนทนานี้ทำให้ฉันนึกถึงการอภิปรายที่ฉันมักจะมีเกี่ยวกับประสิทธิภาพของโค้ดแปลเป็นโค้ดในการประกอบน้อยลงหรือไม่ ดูเหมือนว่าแนวคิดนี้เป็นที่ยอมรับกันโดยทั่วไปว่าเป็นเรื่องจริง เมื่อพิจารณาว่าการติดตามว่า ALU จะจัดการกับแต่ละคำสั่งได้เร็วเพียงใดตัวเลือกที่สองคือการมุ่งเน้นไปที่การกระโดดและเปรียบเทียบในการประกอบ เมื่อเป็นเช่นนั้นความแตกต่างระหว่างคำสั่งบูลีนหรือจำนวนเต็มในโค้ดที่คุณนำเสนอจะค่อนข้างเป็นตัวแทน ผลลัพธ์ของนิพจน์ใน C ++ จะส่งกลับค่าที่จะได้รับการเป็นตัวแทน ในการประกอบในทางกลับกัน การกระโดดและการเปรียบเทียบจะขึ้นอยู่กับค่าตัวเลขโดยไม่คำนึงถึงประเภทของนิพจน์ที่ถูกประเมินกลับมาที่คุณ C ++ if statement เป็นสิ่งสำคัญสำหรับคำถามเหล่านี้ที่ต้องจำไว้ว่าข้อความเชิงตรรกะอย่างหมดจดเช่นสิ่งเหล่านี้จบลงด้วยค่าใช้จ่ายในการคำนวณจำนวนมากแม้ว่าบิตเดียวจะสามารถทำสิ่งเดียวกันได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.