ควรใช้ฟังก์ชั่นอินไลน์เมื่อใดและจะไม่ใช้เมื่อใด


185

ฉันรู้ว่าอินไลน์เป็นคำใบ้หรือคำขอให้คอมไพเลอร์และมันใช้เพื่อหลีกเลี่ยงค่าใช้จ่ายในการโทรฟังก์ชั่น

ดังนั้นสิ่งที่พื้นฐานหนึ่งสามารถกำหนดได้ว่าฟังก์ชั่นเป็นตัวเลือกสำหรับการอินไลน์หรือไม่? ในกรณีใดที่หนึ่งควรหลีกเลี่ยงการอินไลน์


11
inlineคือไปที่ C ++ มาใหม่สิ่งที่CFLAGSจะมาใหม่ Gentoo: ไม่มีการรวบรวมที่มี-O3 -funroll-loops -finline-functionsจะไม่ทำให้ Pentium เก่าของคุณบิน;)
เกรกอรี่ Pakosz

1
เหตุผลที่ไม่ใช้อินไลน์คือผู้ debuggers บางคนจะไม่อนุญาตให้คุณตั้งจุดพักหรือขั้นตอนในฟังก์ชั่นแบบอินไลน์
Rob deFriesse


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

@DavidThornley บางครั้งแม้จะมีการตั้งค่าสถานะ O3 คอมไพเลอร์ไม่ได้อินไลน์ฟังก์ชั่นถ้าคำนิยามอยู่ในไฟล์ cpp ดังนั้นกฎหัวแม่มือที่ฉันทำตามคือการแทรกแถวหนึ่งเส้นและยังทำหน้าที่เหล่านั้นโดยไม่มีลูป
talekeDskobeDa

คำตอบ:


210

การหลีกเลี่ยงค่าใช้จ่ายในการเรียกใช้ฟังก์ชันเป็นเพียงครึ่งเดียวของเรื่องราว

ทำ:

  • ใช้inlineแทน#define
  • ฟังก์ชั่นที่เล็กมากเป็นตัวเลือกที่ดีสำหรับinline: โค้ดที่เร็วขึ้นและ executables เล็ก (โอกาสที่จะอยู่ในแคชของโค้ด)
  • ฟังก์ชั่นมีขนาดเล็กและเรียกบ่อยมาก

ไม่ได้:

  • ฟังก์ชั่นขนาดใหญ่: นำไปสู่การปฏิบัติการที่มีขนาดใหญ่ขึ้นซึ่งจะบั่นทอนประสิทธิภาพการทำงานอย่างมาก
  • ฟังก์ชันแบบอินไลน์ที่ถูกผูกไว้ I / O
  • ฟังก์ชั่นนี้ไม่ค่อยได้ใช้
  • คอนสตรัคเตอร์และ destructors: แม้จะว่างเปล่าคอมไพเลอร์สร้างรหัสสำหรับพวกเขา
  • ทำลายความเข้ากันได้ไบนารีเมื่อพัฒนาห้องสมุด:
    • อินไลน์ฟังก์ชั่นที่มีอยู่
    • เปลี่ยนฟังก์ชั่นแบบอินไลน์หรือทำให้ฟังก์ชั่นแบบอินไลน์ที่ไม่ใช่แบบอินไลน์: รุ่นก่อนหน้าของห้องสมุดเรียกการใช้งานเก่า

เมื่อพัฒนาห้องสมุดเพื่อที่จะทำให้ชั้นเรียนขยายได้ในอนาคตคุณควร:

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

โปรดจำไว้ว่าinlineคำหลักนั้นเป็นคำใบ้ของคอมไพเลอร์: คอมไพเลอร์อาจตัดสินใจที่จะไม่อินไลน์ฟังก์ชั่นและมันสามารถตัดสินใจที่จะอินไลน์ฟังก์ชั่นที่ไม่ได้ทำเครื่องหมายinlineในสถานที่แรก ฉันมักจะหลีกเลี่ยงการทำเครื่องหมายฟังก์ชั่นinline(นอกเหนือจากบางทีเมื่อเขียนฟังก์ชั่นที่เล็กมาก ๆ )

เกี่ยวกับประสิทธิภาพวิธีการที่ชาญฉลาดคือ (เช่นเคย) เพื่อทำโปรไฟล์แอปพลิเคชันจากนั้นinlineชุดของฟังก์ชันที่แสดงถึงคอขวดในที่สุด

อ้างอิง:


แก้ไข: Bjarne Stroustrup, ภาษา C ++ การเขียนโปรแกรม:

inlineฟังก์ชั่นที่สามารถกำหนดให้เป็น ตัวอย่างเช่น:

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

ตัวinlineระบุเป็นคำใบ้ของคอมไพเลอร์ที่ควรพยายามสร้างรหัสสำหรับการโทรfac()แบบอินไลน์แทนที่จะวางโค้ดสำหรับฟังก์ชั่นหนึ่งครั้งแล้วเรียกผ่านกลไกการเรียกฟังก์ชันตามปกติ เรียบเรียงฉลาดสามารถสร้างอย่างต่อเนื่องสำหรับการโทร720 fac(6)ความเป็นไปได้ของฟังก์ชั่นอินไลน์แบบเรียกซ้ำร่วมกันฟังก์ชั่นอินไลน์ที่ชดเชยหรือไม่ขึ้นอยู่กับอินพุต ฯลฯ ทำให้ไม่สามารถรับประกันได้ว่าการเรียกใช้inlineฟังก์ชันทุกครั้งจะถูกขีดเส้นใต้ ระดับของความฉลาดของคอมไพเลอร์ไม่สามารถออกกฏหมายดังนั้นหนึ่งคอมไพเลอร์อาจสร้าง720อีกและอีกสายเรียกยกเลิก6 * fac(5) inlinedfac(6)

เพื่อให้การอินไลน์เป็นไปได้หากไม่มีการรวบรวมและเชื่อมโยงสิ่งอำนวยความสะดวกที่ฉลาดผิดปกติคำจำกัดความ - และไม่ใช่แค่การประกาศ - ของฟังก์ชันอินไลน์ต้องอยู่ในขอบเขต (§9.2) ตัวระบุinlineไม่มีผลต่อความหมายของฟังก์ชัน โดยเฉพาะอย่างยิ่งฟังก์ชั่นแบบอินไลน์ยังคงมีที่อยู่ที่ไม่ซ้ำกันและมีstaticตัวแปร (§7.1.2) ของฟังก์ชั่นอินไลน์

EDIT2: ISO-IEC 14882-1998, 7.1.2 ตัวระบุฟังก์ชั่น

การประกาศฟังก์ชัน (8.3.5, 9.3, 11.4) พร้อมตัวinlineระบุประกาศฟังก์ชันอินไลน์ ตัวระบุอินไลน์บ่งชี้ถึงการใช้งานที่การทดแทนแบบอินไลน์ของร่างกายของฟังก์ชั่นที่จุดของการโทรจะเป็นที่ต้องการกับกลไกการเรียกใช้ฟังก์ชั่นปกติ การดำเนินการไม่จำเป็นต้องดำเนินการทดแทนแบบอินไลน์นี้ ณ จุดที่เรียก; อย่างไรก็ตามแม้ว่าจะมีการละเว้นการแทนที่แบบอินไลน์นี้กฎอื่น ๆ สำหรับฟังก์ชั่นแบบอินไลน์ที่กำหนดโดย 7.1.2 จะยังคงได้รับการเคารพ


34
inlineเป็นมากกว่าคำใบ้ของคอมไพเลอร์ มันเปลี่ยนกฎภาษาเกี่ยวกับคำจำกัดความหลาย ๆ นอกจากนี้การมีข้อมูลสแตติกไม่ใช่เหตุผลเหล็กหล่อเพื่อหลีกเลี่ยงการอินไลน์ฟังก์ชัน การดำเนินการมีหน้าที่ในการจัดสรรวัตถุคงที่เดียวสำหรับแต่ละฟังก์ชั่นคงที่ไม่ว่าจะมีการประกาศฟังก์ชั่นinlineหรือไม่ ชั้นเรียนยังคงขยายได้ถ้าพวกเขามีตัวสร้างแบบอินไลน์และ destructors เสมือน และ braces destructor ที่ว่างเปล่าเป็นฟังก์ชั่นเสมือนหนึ่งที่บางครั้งก็เป็นความคิดที่ดีที่จะออกจากอินไลน์
CB Bailey

2
มันเป็นคำใบ้ในแง่ที่ว่าฟังก์ชั่นนั้นไม่จำเป็นต้องถูกขีดเส้นใต้ (แต่ภาษาอังกฤษไม่ใช่ภาษาแม่ของฉัน) เกี่ยวกับสถิตยศาสตร์ในฟังก์ชั่นการทำเครื่องหมายinlineผลลัพธ์คือฟังก์ชั่นไม่ได้รับการอินไลน์: คุณจ่ายราคาสำหรับการโทรและหน่วยการแปลแต่ละหน่วยที่รวมและการเรียกใช้ฟังก์ชันได้รับสำเนาของรหัสและตัวแปรสแตติกของตัวเอง เหตุผลที่ไม่ inlining ก่อสร้างและ destructors เมื่อมีการพัฒนาห้องสมุดให้เป็นความเข้ากันได้กับไบนารีรุ่นอนาคตของห้องสมุดของคุณ
เกรกอรี่ Pakosz

14
มันไม่ถูกต้องที่จะเรียกมันว่า "คำใบ้ต่อคอมไพเลอร์" ในความเป็นจริงinlineฟังก์ชั่นที่ไม่สามารถ inline ถ้าคอมไพเลอร์รู้สึกเหมือนมัน และinlineฟังก์ชั่นจะไม่ถูกแทรกหากคอมไพเลอร์ตัดสินใจที่จะไม่อินไลน์มัน ดังที่ชาร์ลส์เบลีย์พูดมันเปลี่ยนกฎภาษา แทนที่จะคิดว่ามันเป็นการเพิ่มประสิทธิภาพคำแนะนำมันถูกต้องมากกว่าที่จะคิดว่ามันเป็นแนวคิดที่แตกต่างอย่างสิ้นเชิง inlineคำหลักบอกคอมไพเลอร์เพื่อให้คำจำกัดความหลายและไม่มีอะไรอื่น การปรับให้เหมาะสมที่สุด "inlining" สามารถใช้ได้กับเกือบทุกฟังก์ชั่นไม่ว่าจะทำเครื่องหมายไว้หรือไม่inlineก็ตาม
jalf

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

2
@GregoryPakosz: แต่เราไม่ได้ใช้ทั้งหมดinlineเพื่อรับฟังก์ชั่นอินไลน์ บางครั้งเราต้องการผลประโยชน์อื่น ๆ เช่นได้รับรอบ ODR
การแข่งขัน Lightness ใน Orbit

57

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

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

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


ฉันรู้สึกว่านี่เป็นเรื่องบังเอิญที่มีความสุขมากกว่าคุณลักษณะโดยเจตนาของ C ++ แนวคิดนี้คล้ายกับตัวแปรทั่วโลก 'คงที่' จาก C. มันเป็นคำตอบที่น่าสนใจมาก ฉันหวังว่าพวกเขาจะใช้คำหลักเช่น 'ภายใน' เพื่อระบุถึงการเชื่อมโยงภายใน
Rehno Lindeque

+1 @ Rehno: ฉันไม่แน่ใจว่าสิ่งที่คุณพูด การเชื่อมโยงเกี่ยวข้องกับinlineคำหลักอย่างไร และเรื่องบังเอิญที่มีความสุขคืออะไร?
jalf

@jalf: การอ่านความคิดเห็นของฉันในการหวนกลับฉันรู้ว่ามันค่อนข้างคลุมเครือและไม่ได้คิดอย่างนั้น การกำหนดฟังก์ชั่นเดียวกันในหลายไฟล์ทำให้เกิดข้อผิดพลาดของ linker ซึ่งสามารถตอบโต้ได้โดยการประกาศฟังก์ชั่น 'static' อย่างไรก็ตาม 'อินไลน์' ช่วยให้คุณสามารถทำสิ่งเดียวกันกับความแตกต่างเล็กน้อยที่พวกเขาไม่ได้รับการเชื่อมโยงภายในเช่น 'คงที่' ทำ ฉันสงสัยว่านี่เป็นเรื่องบังเอิญมากกว่าเพราะผู้ใช้ภาษา / ผู้ออกแบบตระหนักว่าพวกเขาจะต้องทำสิ่งพิเศษด้วยฟังก์ชั่นที่ประกาศในไฟล์ส่วนหัวและที่นำไปสู่ ​​'อินไลน์'
Rehno Lindeque

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

10

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

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

คุณอาจประหลาดใจแม้ว่า - คอมไพเลอร์ C ++ หลายคนจะอินไลน์ฟังก์ชั่นเล็ก ๆ ให้คุณโดยอัตโนมัติและพวกเขาอาจเพิกเฉยต่อคำขออินไลน์ของคุณเช่นกัน


แน่นอนฉันสงสัยว่าผู้รวบรวมบางรายแอบดู 'อินไลน์' อย่างสมบูรณ์และตอบสนองต่อ '__inline' หรือ '__force_inline' เท่านั้น ฉันคิดว่านี่คือการยับยั้งการละเมิด!
Rehno Lindeque

ไม่ปกติกรณี อินไลน์เป็นเพียงคำใบ้ แต่เป็นคำแนะนำที่คอมไพเลอร์ส่วนใหญ่ให้ความสำคัญ คุณสามารถตั้งค่าคอมไพเลอร์เพื่อปล่อยภาษาแอสเซมบลีพร้อมกับรหัสวัตถุ ( /FAcsใน Visual Studio -sใน GCC) เพื่อดูว่ามันทำอะไร จากประสบการณ์ของฉันคอมไพเลอร์ทั้งสองมีน้ำหนักคำหลักอินไลน์ค่อนข้างมาก
Crashworks

1
เป็นเรื่องที่น่าสนใจเพราะจากประสบการณ์ของฉันไม่ว่าจะเป็นinlineคำหลักน้ำหนัก g ++ หรือ VC เลย นั่นคือถ้าคุณเห็นฟังก์ชั่นที่ถูก inline และลบinlinespecifier จากมันก็จะยังคงได้รับการ inline หากคุณมีตัวอย่างที่เฉพาะเจาะจงของสิ่งที่ตรงกันข้ามโปรดแบ่งปันพวกเขา!
Pavel Minaev

4
วิธีการที่ไม่inlineขัดขวางคำว่า "รหัสที่ชัดเจน"? คำหลักใน "การเพิ่มประสิทธิภาพก่อนวัยอันควร" คือก่อนกำหนดไม่ใช่การเพิ่มประสิทธิภาพ การบอกว่าคุณควรหลีกเลี่ยงการเพิ่มประสิทธิภาพอย่างจริงจัง *เป็นเพียงขยะ จุดอ้างอิงนั้นคือคุณควรหลีกเลี่ยงการปรับให้เหมาะสมที่อาจไม่จำเป็นและมีผลข้างเคียงที่เป็นอันตรายต่อรหัส (เช่นทำให้สามารถบำรุงรักษาได้น้อยลง) ฉันล้มเหลวในการดูว่าinlineคำหลักจะทำให้รหัสสามารถบำรุงรักษาได้น้อยลงหรือวิธีที่อาจเป็นอันตรายต่อการเพิ่มลงในฟังก์ชัน
jalf

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

5

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

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


4

การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากฐานของความชั่วร้ายทั้งหมด!

ตามกฎของหัวแม่มือฉันมักจะแทรก "getters" และ "setters" เท่านั้น เมื่อโค้ดทำงานและมีความเสถียรการทำโปรไฟล์สามารถแสดงว่าฟังก์ชันใดที่จะได้ประโยชน์จากการอินไลน์

ในทางกลับกันคอมไพเลอร์สมัยใหม่ส่วนใหญ่มีอัลกอริธึมการปรับให้เหมาะสมค่อนข้างดี

Reasuming - เขียนฟังก์ชั่นหนึ่งซับในบรรทัดและกังวลเกี่ยวกับผู้อื่นในภายหลัง


2

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

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับอินไลน์ในc ++ faq


1

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

void IncreaseCount() { freeInstancesCnt++; }

ผู้อ่านรู้ได้ทันทีถึงความหมายที่สมบูรณ์ของรหัส


0

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


0

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


0

เมื่อตัดสินใจว่าจะใช้แบบอินไลน์ฉันมักจะคำนึงถึงความคิดต่อไปนี้: ในการแฝงหน่วยความจำของเครื่องที่ทันสมัยอาจเป็นคอขวดที่ใหญ่กว่าการคำนวณแบบดิบ ฟังก์ชั่นอินไลน์ที่เรียกว่ามักจะเป็นที่รู้จักกันในการขยายขนาดที่ปฏิบัติการ นอกจากนี้ฟังก์ชั่นดังกล่าวสามารถเก็บไว้ในแคชรหัสของ CPU ซึ่งจะลดจำนวนของแคชที่หายไปเมื่อจำเป็นต้องเข้าถึงรหัสนั้น

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

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

  • รูทีนแบบสั้นที่เรียกว่าในการวนรอบแบบแน่น
  • accessors พื้นฐานมาก (รับ / ชุด) และฟังก์ชั่น wrapper
  • รหัสเทมเพลตในไฟล์ส่วนหัวน่าเสียดายที่ได้รับคำแนะนำแบบอินไลน์โดยอัตโนมัติ
  • รหัสย่อที่ใช้เหมือนแมโคร (เช่นนาที () / สูงสุด ())
  • กิจวัตรคณิตศาสตร์สั้น ๆ

0

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

เมื่อinlineวิธีการถูกถ่ายโอนไปยังไฟล์ต้นฉบับและไม่ได้ inlined อีกโครงการทั้งหมดจะต้องสร้างใหม่ (อย่างน้อยก็เป็นประสบการณ์ของฉัน) และเมื่อมีการแปลงวิธีการเป็นแบบอินไลน์


1
นั่นเป็นปัญหาที่แตกต่าง คุณได้รับปัญหาการสร้างใหม่สำหรับรหัสที่อยู่ในไฟล์ส่วนหัว ไม่ว่าจะมีการทำเครื่องหมายinlineหรือไม่ไม่สำคัญ (นอกเหนือโดยไม่ต้องinlineคำหลักที่คุณจะได้รับข้อผิดพลาดลิงเกอร์ - แต่inlineคำหลักไม่เป็นปัญหาที่ก่อให้เกิดการสร้างใหม่มากเกินไป.
jalf

อย่างไรก็ตามการเปลี่ยนวิธีการแบบอินไลน์จะทำให้การสร้างมากเกินไปเมื่อเทียบกับการเปลี่ยนวิธีการที่ไม่ใช่แบบอินไลน์ในไฟล์ shource
Thomas Matthews

0

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


0

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


-2

ฉันอ่านคำตอบแล้วเห็นว่ามีบางอย่างขาดหายไป

กฎที่ฉันใช้คือไม่ใช้อินไลน์ยกเว้นว่าฉันต้องการให้เป็นแบบอินไลน์ ดูเหมือนโง่ตอนนี้คำอธิบาย

คอมไพเลอร์ฉลาดพอและฟังก์ชั่นระยะสั้นทำให้อินไลน์เสมอ และไม่ทำให้ฟังก์ชั่นแบบยาวเป็นแบบอินไลน์เว้นแต่โปรแกรมเมอร์จะทำเช่นนั้น

ฉันรู้ว่าอินไลน์เป็นคำใบ้หรือคำขอให้คอมไพเลอร์

อันที่จริงinlineคือคำสั่งสำหรับคอมไพเลอร์มันไม่มีตัวเลือกและหลังจากinlineคำหลักทำให้โค้ดทั้งหมด ดังนั้นคุณไม่สามารถใช้inlineคำหลักและคอมไพเลอร์จะออกแบบรหัสที่สั้นที่สุด

ดังนั้นควรใช้เมื่อinlineใด

หากต้องการใช้หากคุณต้องการมีรหัสแบบอินไลน์ ฉันรู้เพียงตัวอย่างเดียวเพราะฉันใช้มันในสถานการณ์เดียวเท่านั้น มันคือการตรวจสอบผู้ใช้

เช่นฉันมีฟังก์ชั่นนี้:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

ไม่ว่าฟังก์ชั่นนี้จะใหญ่แค่ไหนก็ตามเพราะมันทำให้ซอฟต์แวร์แตกได้ยากขึ้น


2
อินไลน์ยังคงเป็นคำใบ้ คอมไพเลอร์สามารถล้มเหลวในการอินไลน์ถ้าเห็นว่าฟังก์ชั่นของคุณป่องเกินไป
It'sPete

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

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