เป็นประโยชน์หรือไม่ที่จะละทิ้ง STL ในการพัฒนา C ++? [ปิด]


19

ฉันรู้ว่าในบางพื้นที่ (เช่นอุตสาหกรรมเกม) ไม่แนะนำให้ใช้ STL ดังนั้นคำถามของฉันคือจริง ๆ แล้วมันเป็นการปฏิบัติที่ดีที่จะไม่ใช้ STL ในบางกรณีหรือไม่? ถ้าเป็นเช่นนั้นเหตุผลที่ดีที่สุดที่ไม่ใช้ STL ของ C ++ สมัยใหม่คืออะไร



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

สำหรับการข้ามสิ่งต่าง ๆ ในระหว่างการดีบักดูตัวอย่าง: stackoverflow.com/questions/2062881/…
Martin Ba

ดูเหมือนว่าเป็นคำถามที่ดี อาจมีบางคนเพิ่ม "ทำไมโครงการจะเลือกไม่ใช้ STL"
Matthew James Briggs

คำตอบ:


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

  • ฉันสามารถนึกถึงเหตุผลที่ไม่ถูกต้อง แต่สาเหตุที่พบบ่อยมาก: นักพัฒนาที่ไม่เข้าใจความซับซ้อนในการคำนวณใช้ STL ในทางที่ผิดแล้วตำหนิห้องสมุด

    โดยทั่วไปแล้ว STL จะเร็วกว่ารันไทม์มากกว่าโซลูชันแบบ C ที่มีตัวชี้การโทรกลับหรือโซลูชันที่ใช้ความหลากหลายด้วยวิธีเสมือน ( ดูคำปราศรัยสำคัญของ Bjarne Stroustrup ) อย่างไรก็ตามเมื่อนักพัฒนาไม่เข้าใจข้อกำหนดความซับซ้อนที่กำหนดและใช้ไลบรารีในทางที่ผิดโดยการสร้างเวกเตอร์ของเวกเตอร์ของวัตถุที่ซับซ้อนบางอย่าง (ใน C ++ 11 มันไม่ใช่ปัญหาอีกต่อไป แต่!) ทำให้เกิดปัญหาประสิทธิภาพและป้องกันตัวเอง ด้วย "คุณเห็นว่าเวกเตอร์ค่อนข้างช้า" มันอาจทำให้เกิดการรับรู้ว่าห้องสมุดมาตรฐานช้า และเมื่อผู้จัดการได้รับการรับรู้เช่นนั้นก็สามารถอยู่ในองค์กรได้นานมาก

  • เห็นได้ชัดว่าคุณไม่สามารถใช้สิ่งใดก็ตามที่แพลตฟอร์มที่คุณกำหนดเป้าหมายไม่สนับสนุน อย่างไรก็ตามเรากำลังกำหนดเป้าหมายแพลตฟอร์มมือถือที่ใช้กันมากที่สุดสี่แห่ง (Android, iOS, Bada และ WinCE แบบเก่า) และใช้ไลบรารีมาตรฐานและบางส่วนของBoostในทุกแพลตฟอร์ม

    ไลบรารีมาตรฐานส่วนใหญ่เคยได้รับการสนับสนุนโดย Microsoft ในช่วงต้นของ WinCE (IIRC iostreams ออกมาพร้อมกับ Visual Studio 2005) เท่านั้น แต่ก็เป็นไปได้ที่จะใช้STLportนานกว่านั้นแทน และโดยปกติคุณสามารถรวบรวมสิ่งนั้นได้ ดังนั้นฉันจะเรียกเหตุผลนี้ว่าไม่ถูกต้องเช่นกัน

    นอกจากนี้เป็นเวลานานไม่ใช่ "STL" แต่เป็น ANSI C ++ Standard Library มันถูกกำหนดโดยเอกสารมาตรฐานเดียวกันกับที่กำหนดภาษาเอง อะไรก็ตามที่ไม่สนับสนุนมันไม่สมควรถูกเรียกว่า C ++


6
อาร์กิวเมนต์แรก (เรียลไทม์) ไม่เฉพาะเจาะจงกับส่วน STL ของไลบรารีมาตรฐาน sprintfมักจะจัดสรรหน่วยความจำด้วย ในแพลตฟอร์มเรียลไทม์ฟังก์ชันไลบรารีมาตรฐานก็มีข้อ จำกัด ที่กำหนดไว้เช่นกัน สิ่งนี้ทำให้การปรับใช้ C ++ แบบเรียลไทม์ยาก: คุณต้องพัฒนาทั้งไลบรารีมาตรฐาน C ++ อย่างระมัดระวังซึ่งทำงานได้ดีกว่าไลบรารี่มาตรฐานขนาดเล็ก C เท่านั้น
MSalters

@MSalters: แน่นอนว่ามีหลายสิ่งที่ไม่สามารถใช้งานได้ภายใต้ข้อกำหนดแบบเรียลไทม์ แม้แต่ฟีเจอร์ภาษาบางอย่างเช่นข้อยกเว้นก็ทำไม่ได้ C ++ ยังเป็นภาษาที่ยอดเยี่ยมสำหรับระบบเหล่านี้เนื่องจากสามารถรวมประสิทธิภาพและการควบคุมที่แม่นยำเข้ากับการป้องกันที่แข็งแกร่ง (RAII เป็นคุณลักษณะที่สำคัญที่สุดสำหรับระบบนั้น)
Jan Hudec

@JanHudec: จริง ๆ แล้วนั่นเป็นเหตุผลว่าทำไมส่วน STL จำเป็นสำหรับการใช้งานแบบ "โฮสต์" ของ C ++ เท่านั้น
MSalters

7

ฉันใช้ STL และเพิ่มหลายปีแล้ว หากฉันต้องการละทิ้งมันและใช้เครื่องมือที่กำหนดเองของฉันแรงจูงใจจะเป็น:

  1. เวลาในการคอมไพล์ลดลง (75%) เพียงแค่รวม iostreams สามารถเพิ่มโค้ด 1 ล้านบรรทัดในโมดูลของคุณ ใช่ส่วนหัวที่คอมไพล์แล้วช่วยได้มาก แต่ก็ยังทำให้การรวบรวมในโครงการใหญ่ช้าลง ในระยะยาวมันเสียเวลามากกับทุกคนที่ทำงานกับมัน
  2. ประสิทธิภาพ. (25%) STL เขียนขึ้นเพื่อใช้งานโดยทั่วไป แต่คุณสามารถปรับโครงสร้างของคุณให้ทำงานได้อย่างที่ต้องการ ตัวอย่างเช่นคุณอาจมีโครงสร้างข้อมูลที่มีสตริงสั้น ๆ นับล้าน มันอาจจะเร็วกว่าที่จะใช้คลาสสตริงที่กำหนดเองโดยใช้หลักการของ boost :: small_vector (เวกเตอร์สแตติกท้องถิ่นขนาดเล็กของข้อมูลการจัดสรรแบบไดนามิกเฉพาะสำหรับสตริงขนาดใหญ่) การเปลี่ยนแปลงประเภทนี้สามารถทำให้ส่วนสำคัญของโค้ดทำงานเร็วขึ้นหลายเท่า

1
SSO เป็นเรื่องปกติอยู่แล้ว
Deduplicator

สำหรับลูกหลาน: SSO -> การเพิ่มประสิทธิภาพสตริงขนาดเล็กเช่นส่วนใหญ่ (ทั้งหมด?) การใช้งานสตริง :: เก็บสายเล็ก ๆ ในกองและสลับไปที่กองถ้าจำเป็นต้องเป็น
สีฟ้า

เวลาในการรวบรวมเป็นเรื่องใหญ่
user1754322

4

มีเหตุผลสำคัญข้อหนึ่งที่จะไม่ใช้ไลบรารีเทมเพลตมาตรฐาน C ++: หนึ่งในแพลตฟอร์มเป้าหมายของคุณไม่มีการนำไปปฏิบัติอย่างสมบูรณ์ (หรือไม่มีการนำไปใช้เลย) และคุณรู้ว่าจะไม่ได้รับ ภายในปีหน้า


3
Aka "อย่าใช้เมื่อคุณไม่มี" ซึ่งก็สมเหตุสมผลดีจริงๆ :)
Xeo

4
ระบุว่าไลบรารีมาตรฐาน C ++ 03 ได้รับการออกแบบให้นำไปใช้ในแง่ของไลบรารี ANSI C89 เท่านั้นมีแพลตฟอร์มใดบ้างที่คุณไม่สามารถรับSTLPortอย่างน้อยที่สุดได้หรือไม่
Jan Hudec

@JanHudec ฉันเชื่อว่ามีแพลตฟอร์มที่ไม่มี STL เพราะมีหน่วยความจำไม่เพียงพอที่จะจัดการกับสิ่งทั้งหมด โดยปกติแล้วพวกเขายังขาดฟังก์ชัน C ++ อื่น ๆ (เช่นข้อยกเว้น)
Sulthan

2
@Sulthan: สำหรับไมโครคอนโทรลเลอร์ฉันเข้าใจ แต่คนที่อยู่ในหมวดหมู่ "เรียลไทม์ยาก" มักจะ สำหรับสิ่งอื่น ๆ นั่นคือความคิดส่วนใหญ่เนื่องจาก STL มักจะมีประสิทธิภาพทั้งในเรื่องของความจำและประสิทธิภาพที่ฉลาดพอ ๆ กับโค้ดที่สร้างขึ้นด้วยมือ การอินไลน์จำนวนมากอาจทำให้ไบนารีใหญ่ขึ้น แต่ก็สามารถหลีกเลี่ยงได้โดยการนำไปปฏิบัติอย่างระมัดระวังในราคาประสิทธิภาพบางอย่าง (ซึ่งโซลูชันที่สร้างขึ้นด้วยมือก็มีเช่นกัน) ข้อยกเว้นที่ขาดหายไปนั้นก็เป็นแนวคิดก่อนหน้าหรือความเกียจคร้านเพราะมันใช้ความพยายามในการกำหนดและใช้ข้อยกเว้น ABI
Jan Hudec

4

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

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


2
Qt ที่เทียบเท่านั้นถูกสร้างขึ้นเมื่อไม่มีการใช้งาน STL ที่เป็น a) ที่มีอยู่หรือ b) สิ่งที่ดีใด ๆ นั่นเป็นเหตุผลเดียวที่พวกเขายังคงใช้ไม่มีอะไรเทียบกับ STL ของวันนี้
gbjbaanb

1
@Giorgio: ปัญหาอยู่ในแอปพลิเคชั่นที่ซับซ้อนซึ่งคุณกำลังรวมหลายไลบรารี ภาชนะ STL เป็นมาตรฐานในรูปแบบภาษากลาง แม่นยำยิ่งขึ้นมันเป็นอนุสัญญาที่ทำ ตัวอย่างที่รู้จักกันดีที่สุดคือ Boost มันสามารถทำงานกับภาชนะ STL มันยังสามารถทำงานกับภาชนะ Qt แต่เพียงเพราะ Qt ได้ปฏิบัติตามอนุสัญญา STL - เช่นQList<T>::iterator
MSalters

3
ฉันไม่ได้ลงคะแนน แต่ฉันเห็นเหตุผลหนึ่งข้อ: มันไม่ตอบคำถาม คุณบอกว่ามีสิ่งต่าง ๆ ให้ใช้แทน STL แต่ก็ไม่มีเหตุผลที่จะหลีกเลี่ยง STL นอกจากเหตุผลใด ๆ ในการหลีกเลี่ยง STL อาจใช้กับ Qt, MFC และไลบรารีอื่น ๆ เช่นกันหรือมากกว่านั้น
Jan Hudec

3
@NOOne: เราเข้าใจว่าคุณคุ้นเคยกับการตั้งแคมป์แล้วไม่ใช่ snakecase แต่นั่นไม่ได้ทำให้แย่ลงไปกว่านี้ และจากชื่อฟังก์ชั่นทั้งสามที่คุณวิพากษ์วิจารณ์ชื่อแรกนั้นเป็นคำอธิบายที่สมบูรณ์แบบสำหรับผู้ที่มีส่วนเกี่ยวข้องกับ c-strings และอีกสองชื่อนั้นสืบทอดมาจาก C จะไม่พูดถึงสิ่งเหล่านั้น
Deduplicator

1
@NOOne: อย่างที่ฉันพูดฉันได้รับทั้งหมดว่าคุณสบายใจกับ CamelCase
Deduplicator

3

Patrick ได้กล่าวถึงเหตุผลที่ไม่ใช้ STL ทั้งหมดนั่นคือแพลตฟอร์มของคุณไม่มี

โดยรวมแล้วฉันคิดว่าคำถามนั้นไม่มีจุด ส่วนใหญ่ไม่ใช่การตัดสินใจทั้งหมดหรือไม่มีอะไรเลย แต่เป็นหนึ่งในการเลือกและเลือก คุณอาจตัดสินใจที่จะไปกับคอนเทนเนอร์และอัลกอริทึม แต่ตัดสินใจที่จะใช้บางสิ่งบางอย่างนอก Std Lib สำหรับสตริงและ i / o


3

มันไม่สามารถใช้งานได้เว้นแต่จะมีเหตุผลอย่างมากที่ต้องทำเช่นนั้น เหตุผลบางประการที่ฉันคิดว่ารวมเพียงบางส่วนหรือขาดการใช้ STL (หรือส่วนอื่น ๆ ของไลบรารีมาตรฐาน) หรือข้อ จำกัด ทรัพยากร (หน่วยความจำ, ความเร็วของ CPU, ที่เก็บข้อมูล, ... ) ที่คุณต้องหลีกเลี่ยง กลิ้งเครื่องมือของคุณเองซึ่งเป็นไปตามสิ่งที่คุณต้องทำให้สำเร็จ

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

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


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

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

2
มันควรจะกล่าวว่ามันเป็นประสบการณ์เก่าแก่ที่อาศัยอยู่ เครื่องมือเพิ่มประสิทธิภาพที่ทันสมัยมักจะสร้างแอสเซมบลีที่ดีขึ้นจากรหัสที่บำรุงรักษาง่ายกว่าโปรแกรมเมอร์จะทำด้วยมือและแม่แบบทั่วไปเช่นใน STL หรือ Boost มักจะอินไลน์เป็นรหัสที่มีประสิทธิภาพเป็นปลอกพิเศษทุกอย่างด้วยมือ แต่มีรหัสจำนวนมากที่เริ่มต้นในช่วงเวลาที่ไม่ใช่กรณีและผู้คนจำนวนมากที่เรียนรู้การค้าในสมัยนั้นและทำงานต่อไปแม้ว่ามันจะไม่สมเหตุสมผลอีกต่อไป
Jan Hudec

2
@JanHudec สิ่งที่ต้องทำคือการปรับใช้ (และพฤติกรรมด้วยความไม่เข้าใจ) ให้เหมาะสมกับงาน คุณเพียงแค่ไม่สามารถสำรองสักสองสามสิบไบต์ที่นี่และที่นั่น (ทำลายสถานที่อ้างอิง) ลดลงในไม่กี่สาขาเพื่อตรวจสอบการป้อนข้อมูล (สาขาผิดคาดการณ์และการเรียนการสอนแคชคิดถึง) และคิดว่าคอมไพเลอร์รู้วิธีการปรับโครงสร้างข้อมูลของคุณ อย่างเหมาะสมเพื่อใช้ประโยชน์จาก SIMD (ไม่หรืออย่างน้อยคุณต้องยืนยันว่าสิ่งที่พยายามทำนั้นถูกต้อง) แน่นอนว่าการเขียนซอฟต์แวร์แบบเรียลไทม์บนพีซีนั้นไม่เข้มงวดเท่าไหร่คุณสามารถโยนซีพียูได้เร็วขึ้น ไม่อยู่ในคอนโซล
zxcdw
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.