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


32

เมื่อฉันเรียนรู้ภาษา C ++ เป็นครั้งแรกที่ฉันได้เรียนรู้ว่านอกเหนือจาก int, float ฯลฯ รุ่นข้อมูลขนาดเล็กหรือใหญ่กว่านั้นมีอยู่ในภาษา ตัวอย่างเช่นฉันสามารถเรียกตัวแปร x

int x;
or 
short int x;

ความแตกต่างที่สำคัญคือการที่ short int ใช้หน่วยความจำ 2 ไบต์ในขณะที่ int ใช้ 4 ไบต์และ short int มีค่าน้อยกว่า แต่เราสามารถเรียกสิ่งนี้ว่าทำให้มันเล็กลงได้:

int x;
short int x;
unsigned short int x;

ซึ่ง จำกัด มากยิ่งขึ้น

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


3
คุณรู้หรือไม่เกี่ยวกับรูปแบบการออกแบบ Flyweight ? "วัตถุที่ลดการใช้หน่วยความจำให้น้อยที่สุดโดยการแบ่งปันข้อมูลให้มากที่สุดเท่าที่เป็นไปได้กับวัตถุอื่น ๆ ที่คล้ายกันมันเป็นวิธีการใช้วัตถุเป็นจำนวนมากเมื่อการแสดงซ้ำ ๆ อย่างง่าย ๆ จะใช้หน่วยความจำที่ยอมรับไม่ได้ ... "
gnat

5
ด้วยการตั้งค่าคอมไพเลอร์มาตรฐานการบรรจุ / การจัดตำแหน่งตัวแปรจะถูกจัดตำแหน่งให้อยู่ในขอบเขต 4 ไบต์ต่อไปดังนั้นจึงไม่มีความแตกต่างเลย
nikie

36
กรณีคลาสสิกของการเพิ่มประสิทธิภาพก่อนวัยอันควร
scarfridge

1
@nikie - พวกเขาอาจถูกจัดตำแหน่งในขอบเขต 4 ไบต์บนโปรเซสเซอร์ x86 แต่นี่ไม่เป็นความจริงโดยทั่วไป MSP430 จะวางอักขระไว้บนที่อยู่ไบต์ใดก็ได้และทุกอย่างจะอยู่ที่ไบต์คู่ ฉันคิดว่า AVR-32 และ ARM Cortex-M เหมือนกัน
uɐɪ

3
ส่วนที่ 2 ของคำถามของคุณบอกเป็นนัยว่าการเพิ่มunsignedอย่างใดทำให้จำนวนเต็มใช้พื้นที่น้อยลงซึ่งแน่นอนว่าเป็นเท็จ มันจะมีจำนวนที่เหมือนกันของค่าที่ไม่ต่อเนื่องแทน (ให้หรือใช้ 1 ขึ้นอยู่กับวิธีการแสดงสัญญาณ) แต่เพียงแค่เปลี่ยนเป็นค่าบวก
underscore_d

คำตอบ:


41

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

unsigned int salary;

คุณให้ข้อมูลที่เป็นประโยชน์กับนักพัฒนารายอื่น: เงินเดือนไม่สามารถเป็นค่าลบได้

ความแตกต่างระหว่าง short, int, long จะไม่ทำให้เกิดปัญหาพื้นที่ในแอปพลิเคชันของคุณ คุณมีแนวโน้มที่จะใช้สมมติฐานที่ผิดพลาดโดยไม่ตั้งใจว่าตัวเลขจะเหมาะกับประเภทข้อมูลบางประเภทเสมอ มันอาจจะปลอดภัยกว่าที่จะใช้ int เสมอเว้นแต่คุณจะแน่ใจ 100% ว่าตัวเลขของคุณจะเล็กมาก ถึงอย่างนั้นมันก็ไม่น่าจะช่วยให้คุณประหยัดพื้นที่ที่เห็นได้ชัดเจน


5
ความจริงมันไม่ค่อยจะทำให้เกิดปัญหาในทุกวันนี้ แต่ถ้าคุณออกแบบห้องสมุดหรือชั้นเรียนที่ผู้พัฒนารายอื่นจะใช้มันก็เป็นอีกเรื่องหนึ่ง บางทีพวกเขาอาจต้องการพื้นที่เก็บข้อมูลสำหรับวัตถุเหล่านี้เป็นล้าน ๆ ชิ้นซึ่งในกรณีนี้ความแตกต่างมีขนาดใหญ่ - 4MB เมื่อเทียบกับ 2MB สำหรับฟิลด์นี้
dodgy_coder

30
การใช้unsignedในกรณีนี้เป็นความคิดที่ไม่ดี: ไม่เพียง แต่เงินเดือนไม่สามารถเป็นลบได้ แต่ความแตกต่างระหว่างเงินเดือนสองรายการไม่สามารถเป็นลบได้เช่นกัน (โดยทั่วไปใช้ที่ไม่มีการลงชื่ออะไร แต่บิต twiddling และมีพฤติกรรมที่กำหนดไว้ในหน่วยความจำล้นเป็นความคิดที่ไม่ดี.)
zvrba

15
@zvrba: ความแตกต่างระหว่างสองเงินเดือนไม่ใช่ตัวเองเป็นเงินเดือนดังนั้นจึงเป็นเรื่องถูกต้องที่จะใช้ประเภทอื่นที่ลงนาม
JeremyP

12
@JeremyP ใช่ แต่ถ้าคุณใช้ C (และดูเหมือนว่านี่เป็นความจริงใน C ++ ด้วย) การลบจำนวนเต็มที่ไม่ได้ลงนามจะทำให้เกิด int ที่ไม่ได้ลงนามซึ่งไม่สามารถลบได้ มันอาจเปลี่ยนเป็นค่าที่ถูกต้องหากคุณส่งไปยัง int ที่ลงนามแล้ว แต่ผลลัพธ์ของการคำนวณนั้นเป็น int ที่ไม่ได้ลงนาม ดูคำตอบนี้สำหรับความแปลกประหลาดในการคำนวณที่ลงชื่อและไม่ได้ลงชื่อเพิ่มเติม - ซึ่งเป็นสาเหตุที่คุณไม่ควรใช้ตัวแปรที่ไม่ได้ลงชื่อเว้นแต่คุณจะเป็นบิตที่เล่น ๆ
Tacroy

5
@zvrba: ความแตกต่างคือปริมาณเงิน แต่ไม่ใช่เงินเดือน ตอนนี้คุณอาจยืนยันว่าเงินเดือนก็เป็นปริมาณทางการเงิน (จำกัด ให้เป็นตัวเลขบวกและ 0 โดยการตรวจสอบอินพุตซึ่งเป็นสิ่งที่คนส่วนใหญ่จะทำ) แต่ความแตกต่างระหว่างเงินเดือนสองตัวไม่ใช่เงินเดือนเอง
JeremyP

29

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

หากคุณเข้าสู่โลกของระบบฝังตัว - ซึ่งไม่ได้อยู่นอกขอบเขตของคำถามเนื่องจาก OP ไม่ได้ จำกัด เฉพาะพีซีเท่านั้นดังนั้นขนาดของประเภทข้อมูลจึงมีความสำคัญมาก ฉันเพิ่งเสร็จสิ้นโครงการด่วนบนไมโครคอนโทรลเลอร์ 8 บิตซึ่งมีหน่วยความจำโปรแกรมเพียง 8K และRAM 368 ไบต์ เห็นได้ชัดว่าทุกไบต์มีค่า หนึ่งไม่เคยใช้ตัวแปรที่ใหญ่กว่าที่พวกเขาต้องการ (ทั้งจากพื้นที่จุดยืนและขนาดรหัส - โปรเซสเซอร์ 8 บิตใช้คำแนะนำมากมายในการจัดการข้อมูล 16 และ 32 บิต) เหตุใดจึงต้องใช้ CPU ที่มีทรัพยากร จำกัด ในปริมาณมากพวกเขาสามารถเสียค่าใช้จ่ายเพียงเล็กน้อยในหนึ่งไตรมาส

ขณะนี้ฉันกำลังทำโครงการฝังตัวอื่นกับไมโครคอนโทรลเลอร์ที่ใช้ MIPS แบบ 32 บิตซึ่งมีแฟลช 512K ไบต์และ RAM ขนาด 128K ไบต์ (และราคาประมาณ $ 6 ในปริมาณ) เช่นเดียวกับพีซีขนาดข้อมูล "ธรรมชาติ" คือ 32 บิต ตอนนี้มันกลายเป็นรหัสที่ฉลาดกว่าที่มีประสิทธิภาพในการใช้ ints สำหรับตัวแปรส่วนใหญ่แทนที่จะเป็นตัวอักษรหรือกางเกงขาสั้น แต่อีกครั้งอาร์เรย์หรือโครงสร้างใด ๆ จะต้องได้รับการพิจารณาว่ามีการรับประกันชนิดข้อมูลขนาดเล็กลงหรือไม่ ซึ่งแตกต่างจากคอมไพเลอร์สำหรับระบบขนาดใหญ่มันเป็นตัวแปรที่มีแนวโน้มมากขึ้นในโครงสร้างที่จะถูกบรรจุในระบบฝังตัว ฉันพยายามที่จะวางตัวแปร 32 บิตทั้งหมดก่อนแล้วค่อยไป 16 บิตและ 8 บิตเพื่อหลีกเลี่ยง "หลุม" ใด ๆ


10
+1 สำหรับความจริงที่ว่ากฎที่แตกต่างนำไปใช้กับระบบฝังตัว ความจริงที่ว่า C ++ นั้นไม่ได้หมายความว่าเป้าหมายนั้นเป็นพีซี หนึ่งในโปรเจ็กต์ล่าสุดของฉันเขียนด้วย C ++ บนโปรเซสเซอร์ที่มี RAM 32k และ Flash 256K
คุณ

13

คำตอบขึ้นอยู่กับระบบของคุณ โดยทั่วไปนี่คือข้อดีและข้อเสียของการใช้ประเภทที่เล็กกว่า:

ข้อดี

  • ประเภทขนาดเล็กใช้หน่วยความจำน้อยกว่าในระบบส่วนใหญ่
  • ประเภทที่เล็กลงจะทำให้การคำนวณรวดเร็วขึ้นในบางระบบ โดยเฉพาะอย่างยิ่งเป็นความจริงสำหรับ float vs double ในหลาย ๆ ระบบ และ int ชนิดที่เล็กกว่าก็ให้โค้ดที่เร็วกว่าอย่างมากในซีพียู 8- หรือ 16 บิต

ข้อเสีย

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

คำแนะนำของฉันคือการเป็นเช่นนี้:

system                             int types

small/low level embedded system    stdint.h with smaller types
32-bit embedded system             stdint.h, stick to int32_t and uint32_t.
32-bit desktop system              Only use (unsigned) int and long long.
64-bit system                      Only use (unsigned) int and long long.

อีกวิธีหนึ่งคุณสามารถใช้int_leastn_tหรือint_fastn_tจาก stdint.h โดยที่ n คือหมายเลข 8, 16, 32 หรือ 64. int_leastn_tแปลว่า "ฉันต้องการให้อย่างน้อย n ไบต์ แต่ฉันไม่สนใจว่าคอมไพเลอร์จัดสรรเป็น ประเภทที่ใหญ่กว่าเพื่อให้เหมาะกับการจัดตำแหน่ง ".

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

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


จุดที่เกี่ยวกับการจัดตำแหน่ง ในโครงการปัจจุบันของฉันการใช้ uint8_t ฟรีบน MSP430 แบบ 16 บิตขัดข้อง MCU ในรูปแบบลึกลับ การใช้ชนิด 8 บิตบนอาร์ก> 8- บิตอาร์คหากไม่ถึงขั้นเสียชีวิตอย่างน้อยก็ไม่มีประสิทธิภาพ: คอมไพเลอร์สร้างคำแนะนำเพิ่มเติม 'และ reg, 0xff' ใช้ 'int / unsigned' เพื่อการพกพาและทำให้คอมไพเลอร์ฟรีจากข้อ จำกัด เพิ่มเติม
alexei

11

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

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

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

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

อีกเหตุผลหนึ่งที่ฉันสามารถนึกถึงส่วนบนสุดของหัวของฉันที่จะใช้ประเภทข้อมูลเฉพาะคือเมื่อคุณพยายามที่จะสื่อสารเจตนาภายในรหัสของคุณ หากคุณใช้ shortint คุณจะบอกนักพัฒนาซอฟต์แวร์รายอื่นว่าคุณอนุญาตตัวเลขบวกและลบภายในช่วงค่าที่น้อยมาก


6

ตามที่scarfridgeแสดงความคิดเห็นนี่คือ

กรณีคลาสสิกของการเพิ่มประสิทธิภาพก่อนวัยอันควร

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

กฎข้อแรกของการเพิ่มประสิทธิภาพโปรแกรม: อย่าทำไม่ทำมัน

กฎข้อที่สองของการเพิ่มประสิทธิภาพโปรแกรม (สำหรับผู้เชี่ยวชาญเท่านั้น!): อย่าทำเลย "

- Michael A. Jackson

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

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

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

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

ด้วยเหตุนี้คอมไพเลอร์สมัยใหม่จึงเพิกเฉยต่อคำแนะนำของคุณ ในฐานะที่เป็นความเห็นของnikie :

ด้วยการตั้งค่าคอมไพเลอร์มาตรฐานการบรรจุ / การจัดตำแหน่งตัวแปรจะถูกจัดตำแหน่งให้อยู่ในขอบเขต 4 ไบต์ต่อไปดังนั้นจึงไม่มีความแตกต่างเลย

สองเดาผู้รวบรวมของคุณที่อันตรายของคุณ

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


3

ความแตกต่างที่สำคัญคือการที่ short int ใช้หน่วยความจำ 2 ไบต์ในขณะที่ int ใช้ 4 ไบต์และ short int มีค่าน้อยกว่า แต่เราสามารถเรียกสิ่งนี้ว่าทำให้มันเล็กลงได้:

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

ประโยชน์ด้านประสิทธิภาพนั้นมีน้อยอย่างไม่น่าเชื่อสำหรับตัวแปรสแต็ก

ด้วยเหตุนี้shortและมีจริงไม่มีใช้ในปัจจุบันและคุณมักจะดีกว่าการใช้longint


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


1
อันที่จริงมีการถือกำเนิดของสภาพแวดล้อม 64 บิตอาจจะแตกต่างกันไปlong intหากคอมไพเลอร์ของคุณคือ LP64 intเป็น 32 บิตและlong64 บิตและคุณจะพบว่าints ยังคงอยู่ในตำแหน่ง 4 ไบต์ (คอมไพเลอร์ของฉันทำเช่นนั้น)
JeremyP

1
@ JeremyP ใช่ฉันพูดอย่างอื่นหรืออะไร?
Pubby

ประโยคสุดท้ายของคุณที่อ้างว่าสั้นและยาวไม่มีประโยชน์จริง นานมีประโยชน์ใช้เฉพาะในกรณีที่เป็นประเภทฐานของint64_t
JeremyP

@ JeremyP: คุณสามารถมีชีวิตอยู่ได้ดีกับ int และยาว
gnasher729

@ gnasher729: คุณจะใช้อะไรถ้าคุณต้องการตัวแปรที่สามารถเก็บค่าได้มากกว่า 65,000 แต่ไม่มากถึงหนึ่งพันล้าน? int32_t, int_fast32_tและlongเป็นตัวเลือกที่ดีทั้งหมดlong longเป็นเพียงสิ้นเปลืองและintไม่พกพาได้
Ben Voigt

3

นี้จะมาจากชนิดของ OOP และ / หรือจุด enterprisey / ใบสมัครของมุมมองและอาจจะไม่ได้ใช้บังคับในบางสาขา / โดเมน แต่ชนิดของฉันต้องการที่จะนำขึ้นแนวคิดของความหลงใหลดั้งเดิม

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

ถ้าเราต้องการอุณหภูมิในรูปแบบเคลวินในโปรแกรมของเราที่เราจะได้ใช้ushortหรือuintหรือสิ่งที่คล้ายกับที่แสดงถึง "ความคิดขององศาเคลวินเชิงลบเป็นเรื่องเหลวไหลและข้อผิดพลาดตรรกะโดเมน" ความคิดที่อยู่เบื้องหลังเรื่องนี้เป็นเสียง แต่คุณไม่ได้ไปตลอดทาง สิ่งที่เรารู้คือเราไม่สามารถมีค่าลบได้ดังนั้นจึงมีประโยชน์ถ้าเราสามารถรวบรวมคอมไพเลอร์เพื่อให้แน่ใจว่าไม่มีใครกำหนดค่าลบให้กับอุณหภูมิเคลวิน นอกจากนี้ยังเป็นความจริงที่ว่าคุณไม่สามารถทำงานในระดับบิตเรตได้ และคุณไม่สามารถเพิ่มน้ำหนัก (กิโลกรัม) ลงในอุณหภูมิ (K) ได้ แต่ถ้าคุณจำลองทั้งอุณหภูมิและมวลเป็นuints เราสามารถทำเช่นนั้นได้

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

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


1

ใช่แน่นอน มันเป็นความคิดที่ดีที่จะใช้uint_least8_tสำหรับพจนานุกรมอาร์เรย์ค่าคงที่ขนาดใหญ่บัฟเฟอร์ ฯลฯ จะดีกว่าที่จะใช้uint_fast8_tสำหรับการประมวลผล

uint8_least_t(ที่เก็บข้อมูล) -> uint8_fast_t(กำลังประมวลผล) -> uint8_least_t(ที่เก็บข้อมูล)

ตัวอย่างเช่นคุณจะพาสัญลักษณ์ 8 บิตจากsourceรหัส 16 บิตจากdictionariesและบางส่วน 32 constantsบิต กว่าที่คุณกำลังประมวลผลการดำเนินงาน 10-15 บิตกับพวกเขาและผล 8 destinationบิต

ลองจินตนาการว่าคุณมีการประมวลผล 2 sourceกิกะไบต์ จำนวนบิตการดำเนินการมีขนาดใหญ่มาก คุณจะได้รับโบนัสสุดคุ้มถ้าคุณจะเปลี่ยนเป็นประเภทรวดเร็วในระหว่างการประมวลผล ประเภทที่รวดเร็วอาจแตกต่างกันไปสำหรับซีพียูแต่ละตระกูล คุณสามารถรวมstdint.hและการใช้งานuint_fast8_t, uint_fast16_t, uint_fast32_tฯลฯ

คุณสามารถใช้uint_least8_tแทนuint8_tการพกพาได้ แต่ไม่มีใครรู้ว่าซีพียูสมัยใหม่จะใช้คุณสมบัตินี้อย่างไร เครื่อง VAC เป็นชิ้นส่วนพิพิธภัณฑ์ ดังนั้นอาจเป็น overkill


1
ในขณะที่คุณอาจมีจุดกับประเภทข้อมูลที่คุณระบุไว้คุณควรอธิบายว่าทำไมพวกเขาถึงดีกว่าไม่ใช่แค่ระบุว่าเป็น สำหรับคนอย่างฉันที่ไม่คุ้นเคยกับประเภทข้อมูลเหล่านั้นฉันต้อง google เพื่อที่จะเข้าใจสิ่งที่คุณกำลังพูดถึง
Peter M
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.