คำถามวิศวกรระดับเริ่มต้นเกี่ยวกับการจัดการหน่วยความจำ


9

ไม่กี่เดือนที่ผ่านมาตั้งแต่ฉันเริ่มต้นตำแหน่งในฐานะนักพัฒนาซอฟต์แวร์ระดับเริ่มต้น ตอนนี้ฉันผ่านโค้งการเรียนรู้บางอย่าง (เช่นภาษาศัพท์แสงไวยากรณ์ของ VB และ C #) ฉันเริ่มมุ่งเน้นที่หัวข้อลึกลับมากขึ้นเพื่อเขียนซอฟต์แวร์ที่ดีขึ้น

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

นี่คือรหัส (ใน VB) และตามด้วยคำถาม

หมายเหตุ: Function GenerateAlert () จะคืนค่าจำนวนเต็ม

Dim alertID as Integer = GenerateAlert()
_errorDictionary.Add(argErrorID, NewErrorInfo(Now(), alertID))    

VS ...

 _errorDictionary.Add(argErrorID, New ErrorInfo(Now(), GenerateAlert()))

ฉันเขียนตอนหลังและเขียนใหม่ด้วย "Dim alertID" เพื่อให้คนอื่นสามารถอ่านได้ง่ายขึ้น แต่นี่คือความกังวลและคำถามของฉัน:

เราควรเขียนสิ่งนี้ด้วย Dim AlertID จริงๆแล้วมันต้องใช้หน่วยความจำมากขึ้น จำกัด แต่มากขึ้นและควรเรียกวิธีนี้หลาย ๆ ครั้งว่าอาจนำไปสู่ปัญหาหรือไม่ . NET จะจัดการกับวัตถุนี้ AlertID อย่างไร ด้านนอกของ. NET ควรกำจัดวัตถุด้วยตนเองหลังการใช้งาน (ใกล้ถึงจุดสิ้นสุดของย่อย)

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


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

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

5
จำนวนเต็มเทียบกับไม่ระบุชื่อ vs จะไม่ใช้หน่วยความจำเพิ่มเติมโดยเฉพาะอย่างยิ่งเนื่องจากจำนวนเต็มไม่ระบุชื่อเป็นเพียงจำนวนเต็มชื่อที่คุณไม่ได้ตั้งชื่อ (คอมไพเลอร์ยังคงมีชื่อ) อย่างน้อยจำนวนเต็มที่ระบุชื่อจะมีขอบเขตที่แตกต่างกันดังนั้นจึงอาจมีชีวิตอีกต่อไป จำนวนเต็มแบบไม่ระบุชื่อจะมีชีวิตอยู่ตราบใดที่วิธีการนั้นต้องการชื่อตัวนั้นจะมีชีวิตอยู่ตราบเท่าที่ผู้ปกครองต้องการ
Joel Etherton

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

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

คำตอบ:


25

"การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากฐานของความชั่วร้ายทั้งหมด (หรืออย่างน้อยที่สุด) ในการเขียนโปรแกรม" - Donald Knuth

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

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


1
มันควรเป็นเงินของใคร? นายจ้างของคุณได้รับประโยชน์จากการเพิ่มทักษะของคุณมากกว่าที่คุณทำ
Marcin

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

2
แปลก. พวกเราบางคนมีชีวิตส่วนตัวและอย่างที่ฉันพูดนายจ้างได้รับประโยชน์หลักจากการวิจัย กุญแจสำคัญคือการไม่ใช้จ่ายตลอดทั้งวัน
Marcin

6
ดีสำหรับคุณ. มันไม่ได้ทำให้มันเป็นกฎสากลจริงๆ นอกจากนี้หากคุณกีดกันคนงานของคุณจากการเรียนรู้ที่ทำงานสิ่งที่คุณทำก็คือกีดกันพวกเขาจากการเรียนรู้และสนับสนุนให้พวกเขาหานายจ้างคนอื่นที่จ่ายค่าพัฒนาพนักงานอย่างแท้จริง
Marcin

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

5

สำหรับโปรแกรม. NET โดยเฉลี่ยของคุณใช่มันคิดมาก อาจมีบางครั้งที่คุณจะต้องการลงไปที่ถั่วและสลักเกลียวของสิ่งที่เกิดขึ้นภายใน. NET แต่สิ่งนี้ค่อนข้างหายาก

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


5

ในฐานะเพื่อนร่วมงานของฉันมักจะพูดว่า:

  1. ทำให้มันใช้งานได้
  2. แก้ไขข้อบกพร่องทั้งหมดทำให้มันทำงานได้อย่างไร้ที่ติ
  3. ทำให้เป็นของแข็ง
  4. ใช้การปรับให้เหมาะสมหากทำงานช้า

ในคำอื่น ๆ โปรดจำไว้เสมอKISS (ทำให้โง่ง่าย ๆ ) เนื่องจาก over-engineering การคิดเกินตรรกะบางอย่างอาจเป็นปัญหาในการเปลี่ยนลอจิกในครั้งต่อไป อย่างไรก็ตามการรักษาความสะอาดรหัสและเรียบง่ายอยู่เสมอการปฏิบัติที่ดี

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


3

เราควรเขียนสิ่งนี้ด้วย Dim AlertID

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

ในความเป็นจริงมันจะใช้หน่วยความจำมากขึ้น

ฉันสงสัยว่ามันไม่ เป็นการเพิ่มประสิทธิภาพที่ค่อนข้างตรงไปตรงมาสำหรับคอมไพเลอร์

ควรเรียกวิธีการนี้หลายครั้งว่าจะนำไปสู่ปัญหาหรือไม่

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

. NET จะจัดการกับวัตถุนี้ AlertID อย่างไร

AlertID ไม่ใช่วัตถุ ผลลัพธ์ของ GenerateAlert () เป็นวัตถุ AlertID เป็นตัวแปรซึ่งหากเป็นตัวแปรเฉพาะที่ก็จะมีช่องว่างที่เกี่ยวข้องกับวิธีการติดตามสิ่งต่าง ๆ

ด้านนอกของ. NET ควรกำจัดวัตถุด้วยตนเองหลังการใช้งาน

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

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

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


2

ทำให้มันทำงานให้มันสะอาดทำให้มันแข็งแล้วทำให้การทำงานเป็นไปอย่างรวดเร็วตามความต้องการในการทำงาน

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

Echoing Christopher (และ Donald Knuth) "การปรับให้เหมาะสมก่อนกำหนดเป็นรากฐานของความชั่วร้ายทั้งหมด" นอกจากนี้ประเภทของการปรับให้เหมาะสมที่คุณกำลังพิจารณานั้นทั้งคู่ (การอ้างอิงถึงวัตถุใหม่ของคุณจะถูกสร้างขึ้นบนสแต็กไม่ว่าคุณจะให้ชื่อในซอร์สโค้ดหรือไม่ก็ตาม) และประเภทที่อาจไม่ทำให้เกิดความแตกต่างในการคอมไพล์ IL ชื่อตัวแปรจะไม่ถูกส่งต่อไปยัง IL ดังนั้นเมื่อคุณประกาศตัวแปรก่อนการใช้งานครั้งแรก (และอาจจะเท่านั้น) ฉันจะเดิมพันเงินเบียร์ที่ IL นั้นเหมือนกันระหว่างสองตัวอย่างของคุณ ดังนั้นผู้ร่วมงานของคุณ 100% ถูกต้อง; คุณกำลังมองหาที่ผิดถ้าคุณกำลังดูตัวแปรที่มีชื่อเทียบกับอินสแตนซ์อินไลน์เพื่อหาสิ่งที่จะเพิ่มประสิทธิภาพ

การใช้ประโยชน์สูงสุดจากไมโครซอฟต์ใน. NET แทบจะไม่คุ้มค่าเลย (ฉันกำลังพูดถึงกรณี 99.99%) ใน C / C ++ บางทีถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่ เมื่อทำงานในสภาพแวดล้อม. NET คุณอยู่ห่างจากโลหะของฮาร์ดแวร์ที่มีค่าใช้จ่ายสูงในการใช้รหัส ดังนั้นเมื่อคุณอยู่ในสภาพแวดล้อมที่บ่งบอกว่าคุณเลิกใช้ความเร็วในการพองแล้วและแทนที่จะมองที่จะเขียนรหัส "ถูกต้อง" หากสิ่งที่อยู่ในสภาพแวดล้อม. NET นั้นทำงานได้ไม่เร็วพอความซับซ้อนของมันก็คือ สูงเกินไปหรือคุณควรพิจารณาทำขนานกัน ต่อไปนี้เป็นตัวชี้พื้นฐานที่จะติดตามเพื่อการปรับให้เหมาะสม ฉันรับประกันคุณในการเพิ่มประสิทธิภาพของคุณ (ความเร็วที่ได้รับสำหรับเวลาที่ใช้) จะสูงขึ้น:

  • การเปลี่ยนรูปร่างของฟังก์ชั่นมีความสำคัญมากกว่าการเปลี่ยนค่าสัมประสิทธิ์ - ความซับซ้อนของ WRT Big-Oh คุณสามารถลดจำนวนขั้นตอนที่ต้องดำเนินการในอัลกอริทึมN 2ครึ่งและคุณยังมีอัลกอริธึมที่ซับซ้อน ครึ่งหนึ่งของเวลาที่เคย หากนั่นคือขอบเขตความซับซ้อนที่ต่ำกว่าสำหรับปัญหาประเภทนี้ดังนั้นให้เป็นเช่นนั้น แต่ถ้ามีวิธีแก้ปัญหา NlogN, เชิงเส้นหรือลอการิทึมของปัญหาเดียวกันคุณจะได้รับมากขึ้นโดยการเปลี่ยนอัลกอริทึมเพื่อลดความซับซ้อนมากกว่าโดยการปรับให้เหมาะสม
  • เพียงเพราะคุณไม่สามารถมองเห็นความซับซ้อนไม่ได้หมายความว่ามันไม่ได้คุ้มค่ากับคุณ - หนึ่งใน liners ที่หรูหราที่สุดในคำว่าทำงานได้อย่างน่ากลัว (ตัวอย่างเช่นตัวตรวจสอบหลักของ Regexเป็นฟังก์ชันที่ซับซ้อนแบบเอกซ์โพเนนเชียล การประเมินเฉพาะที่เกี่ยวข้องกับการหารจำนวนด้วยจำนวนเฉพาะทั้งหมดที่น้อยกว่าสแควร์รูทของมันอยู่ในลำดับของO (Nlog (sqrt (N))) Linq เป็นห้องสมุดที่ยอดเยี่ยมเพราะมันทำให้โค้ดง่ายขึ้น คอมไพเลอร์จะไม่พยายามค้นหาวิธีที่มีประสิทธิภาพมากที่สุดในการดำเนินการค้นหาของคุณคุณต้องรู้ว่าจะเกิดอะไรขึ้นเมื่อคุณใช้เมธอดและเหตุใดเมธอดจึงอาจเร็วกว่าหากวางไว้ก่อนหน้านี้ ผลลัพธ์เดียวกัน
  • OTOH มักจะมีข้อเสียระหว่างความซับซ้อนของแหล่งที่มาและความซับซ้อนของรันไทม์ - SelectionSort นั้นใช้งานง่ายมาก คุณสามารถทำได้ใน 10LOC หรือน้อยกว่านั้น MergeSort ซับซ้อนกว่าเล็กน้อย Quicksort มากขึ้นและ RadixSort ยิ่งขึ้น แต่เมื่ออัลกอริทึมเพิ่มความซับซ้อนในการเขียนโค้ด (และเวลาในการพัฒนา "ล่วงหน้า") พวกมันจะลดความซับซ้อนของรันไทม์ลง MergeSort และ QuickSort คือ NlogN และ RadixSort โดยทั่วไปถือว่าเป็นแบบเส้นตรง (โดยทางเทคนิคแล้วคือ NlogM โดยที่ M เป็นหมายเลขที่ใหญ่ที่สุดใน N)
  • แตกเร็ว - หากมีการตรวจสอบที่สามารถทำได้ในราคาไม่แพงซึ่งมีแนวโน้มว่าจะเป็นจริงและหมายความว่าคุณสามารถเดินหน้าต่อได้ให้ตรวจสอบก่อน ตัวอย่างเช่นหากอัลกอริทึมของคุณใส่ใจเฉพาะตัวเลขที่ลงท้ายด้วย 1, 2 หรือ 3 กรณีที่เป็นไปได้มากที่สุด (ให้ข้อมูลแบบสุ่มสมบูรณ์) คือตัวเลขที่ลงท้ายด้วยหลักอื่นดังนั้นทดสอบว่าตัวเลขไม่ได้ลงท้ายด้วย 1, 2 หรือ 3 ก่อนทำการตรวจสอบใด ๆ เพื่อดูว่าจำนวนสิ้นสุดใน 1, 2 หรือ 3 ถ้าตรรกะหนึ่งชิ้นต้องการ A&B และ P (A) = 0.9 ขณะที่ P (B) = 0.1 ให้ตรวจสอบ B ก่อนยกเว้นว่าถ้า! A!! B (เช่นif(myObject != null && myObject.someProperty == 1)) หรือ B ใช้เวลานานกว่า 9 เท่าในการประเมิน ( if(myObject != null && some10SecondMethodReturningBool()))
  • อย่าถามคำถามใด ๆ ที่คุณรู้คำตอบแล้ว - หากคุณมีเงื่อนไขแบบ "ร่วงหล่น" และเงื่อนไขอย่างน้อยหนึ่งอย่างนั้นขึ้นอยู่กับเงื่อนไขที่ง่ายกว่าซึ่งต้องตรวจสอบด้วยอย่าตรวจสอบทั้งสองอย่าง เหล่านี้อย่างอิสระ ตัวอย่างเช่นหากคุณมีเช็คที่ต้องใช้ A และเช็คที่ต้องใช้ A&& คุณควรตรวจสอบ A และถ้าเป็นจริงคุณควรตรวจสอบ B ถ้า! A แล้ว A & B จึงไม่ต้องกังวล
  • ยิ่งคุณทำอะไรซักอย่างมากเท่าไหร่คุณก็ยิ่งต้องใส่ใจกับสิ่งที่ทำมากขึ้นเท่านั้น - นี่เป็นหัวข้อหลักในการพัฒนาในหลาย ๆ ระดับ ในแง่การพัฒนาทั่วไป "ถ้างานทั่วไปใช้เวลานานหรือเที่ยวยุ่งยิ่งให้ทำไปเรื่อย ๆ จนกว่าคุณจะรู้สึกหงุดหงิดและมีความรู้มากพอที่จะหาวิธีที่ดีกว่า" ในแง่ของรหัสยิ่งมีการเรียกใช้อัลกอริธึมที่ไม่มีประสิทธิภาพมากเท่าไหร่คุณก็ยิ่งได้รับประสิทธิภาพโดยรวมมากขึ้นเท่านั้นโดยปรับให้เหมาะสม มีเครื่องมือการทำโปรไฟล์ที่สามารถประกอบไบนารีและสัญลักษณ์การดีบักและแสดงให้คุณเห็นหลังจากใช้งานบางกรณีแล้วบรรทัดของรหัสใดที่ถูกเรียกใช้มากที่สุด เส้นเหล่านั้นและเส้นที่เรียกใช้เส้นเหล่านั้นเป็นสิ่งที่คุณควรให้ความสนใจมากที่สุดเพราะการเพิ่มประสิทธิภาพใด ๆ ที่คุณบรรลุนั้นจะเพิ่มขึ้นเป็นทวีคูณ
  • อัลกอริทึมลักษณะที่ซับซ้อนมากขึ้นเช่นวิธีที่ซับซ้อนน้อยกว่าถ้าคุณโยนฮาร์ดแวร์พอที่มัน มีบางครั้งที่คุณต้องตระหนักว่าอัลกอริทึมของคุณกำลังเข้าใกล้ขีด จำกัด ทางเทคนิคของระบบ (หรือบางส่วน) ที่คุณกำลังใช้งาน จากจุดนั้นหากจำเป็นต้องเร็วขึ้นคุณจะได้รับมากขึ้นด้วยการใช้ฮาร์ดแวร์ที่ดีกว่า สิ่งนี้ยังใช้กับการขนาน อัลกอริธึมที่ซับซ้อนN 2เมื่อรันบนแกน N จะมีลักษณะเป็นเส้นตรง ดังนั้นหากคุณแน่ใจว่าคุณมีความซับซ้อนน้อยลงสำหรับประเภทอัลกอริทึมที่คุณกำลังเขียนหาวิธีที่จะ "หารและพิชิต"
  • มันเร็วเมื่อมันเร็วพอ - ยกเว้นว่าคุณจะประกอบชิ้นส่วนด้วยมือเพื่อกำหนดเป้าหมายไปยังชิปเฉพาะ อย่างไรก็ตามถ้าคุณไม่ต้องการที่จะเป็นชุดประกอบมือคุณต้องจำไว้เสมอว่าลูกค้าจะเรียกว่า "ดีพอ" อีกครั้ง "การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากฐานของความชั่วร้ายทั้งหมด"; เมื่อลูกค้าของคุณเรียกมันว่าเร็วพอคุณจะทำจนเขาไม่คิดว่ามันเร็วพออีกต่อไป

0

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

คำจำกัดความของ "ใหญ่" จะแตกต่างกันไปตามระบบเป้าหมายของคุณ


0

ฉันต้องการเวอร์ชั่นสองบรรทัดเพราะง่ายกว่าที่จะก้าวผ่านตัวดีบัก สายที่มีการโทรฝังหลายตัวทำให้ยากขึ้น

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