การปรับโค้ดให้เหมาะสม: วิธีที่เหมาะสมที่สุดในการเพิ่มประสิทธิภาพ
เผยแพร่แล้ว: 2022-03-11การเพิ่มประสิทธิภาพการทำงานเป็นหนึ่งในภัยคุกคามที่ใหญ่ที่สุดสำหรับโค้ดของคุณ
คุณอาจจะกำลังคิด ไม่ใช่ คน อื่น ฉันเข้าใจ. การเพิ่มประสิทธิภาพใดๆ อย่างชัดเจนควรเป็นสิ่งที่ดี โดยพิจารณาจากนิรุกติศาสตร์ ดังนั้น ตามธรรมชาติแล้ว คุณอยากจะเก่งในเรื่องนั้น
ไม่เพียงแค่ทำให้ตัวเองแตกต่างจากคนอื่นๆ ในฐานะนักพัฒนาที่ดีกว่า ไม่ใช่แค่เพื่อหลีกเลี่ยงการเป็น “แดน” ใน The Daily WTF แต่เนื่องจากคุณเชื่อว่าการเพิ่มประสิทธิภาพโค้ดเป็นสิ่งที่ควรทำ คุณภูมิใจในงานของคุณ
ฮาร์ดแวร์คอมพิวเตอร์ทำงานเร็วขึ้นและซอฟต์แวร์สร้างได้ง่ายขึ้น แต่สิ่งง่ายๆ ที่คุณ อยากจะทำได้ Dammit มักจะใช้เวลานานกว่าที่แล้วเสมอ คุณส่ายหัวกับปรากฏการณ์นี้ (โดยบังเอิญ รู้จักกันในชื่อ Wirth's Law) และตั้งใจแน่วแน่ที่จะรับมือกับแนวโน้มนั้น
นั่นเป็นเกียรติของคุณ แต่หยุด
แค่หยุด!
คุณตกอยู่ในอันตรายร้ายแรงที่สุดในการขัดขวางเป้าหมายของคุณเอง ไม่ว่าคุณจะมีประสบการณ์ในการเขียนโปรแกรมมากแค่ไหนก็ตาม
ได้อย่างไร? กลับกันเถอะ
ก่อนอื่น การเพิ่มประสิทธิภาพโค้ด คือ อะไร?
บ่อยครั้งเมื่อเรากำหนดมัน เราคิดว่าเราต้องการให้โค้ด ทำงาน ได้ดีขึ้น เรากล่าวว่าการเพิ่มประสิทธิภาพโค้ดคือการเขียนหรือเขียนโค้ดใหม่ ดังนั้นโปรแกรมจึงใช้หน่วยความจำหรือพื้นที่ดิสก์น้อยที่สุด ลดเวลา CPU หรือแบนด์วิดท์เครือข่าย หรือใช้คอร์เพิ่มเติมให้เกิดประโยชน์สูงสุด
ในทางปฏิบัติ บางครั้งเราใช้คำจำกัดความอื่นโดยปริยาย นั่นคือ การเขียนโค้ดให้น้อยลง
แต่รหัสลับๆ ที่คุณกำลังเขียนโดยมีเป้าหมายนั้นมีแนวโน้มที่จะกลายเป็นหนามที่อยู่ด้านข้างของใครบางคนมากกว่า ของใคร? คนโชคร้ายคนต่อไปที่ต้องเข้าใจรหัสของคุณซึ่งอาจเป็นตัวคุณเอง และคนที่ฉลาดและมีความสามารถเช่นคุณ สามารถหลีกเลี่ยงการทำร้ายตัวเองได้: รักษาจุดจบของคุณให้สูงส่งแต่ประเมินวิธีการของคุณใหม่ แม้ว่าจะดูเหมือนเป็นสัญชาตญาณอย่างไม่ต้องสงสัยก็ตาม
ดังนั้นการเพิ่มประสิทธิภาพโค้ดจึงเป็นคำที่คลุมเครือเล็กน้อย นั่นคือก่อนที่เราจะพิจารณาวิธีอื่นๆ ที่สามารถเพิ่มประสิทธิภาพโค้ดได้ ซึ่งเราจะอธิบายไว้ด้านล่าง
เริ่มต้นด้วยการฟังคำแนะนำของเหล่าปราชญ์ในขณะที่เราสำรวจกฎการเพิ่มประสิทธิภาพโค้ดที่มีชื่อเสียงของ Jackson ด้วยกัน:
- อย่าทำมัน
- (สำหรับผู้เชี่ยวชาญเท่านั้น!) อย่า เพิ่ง ทำ .
1. Don't Do It: การวางแนวความสมบูรณ์แบบ
ฉันจะเริ่มต้นด้วยตัวอย่างที่ค่อนข้างน่าอายเมื่อนานมาแล้ว ฉันเพิ่งจะเปียกในโลกของ SQL ที่วิเศษสุด ปัญหาคือ พอเหยียบเค้กแล้วไม่อยากกินอีกเพราะมันเปียกและเริ่มมีกลิ่นเหมือนเท้า
ฉันเพิ่งเริ่มเปียกในโลก SQL ที่ยอดเยี่ยมและมีเค้กและกินมันเกินไป ปัญหาคือ แล้วฉันก็เหยียบเค้ก...
รอ. ให้ฉันกลับออกจากซากรถคันนี้ของคำอุปมาที่ฉันเพิ่งทำและอธิบาย
ฉันกำลังทำการวิจัยและพัฒนาสำหรับแอพอินทราเน็ต ซึ่งฉันหวังว่าวันหนึ่งจะกลายเป็นระบบการจัดการแบบบูรณาการอย่างสมบูรณ์สำหรับธุรกิจขนาดเล็กที่ฉันทำงานอยู่ มันจะติดตามทุกอย่างสำหรับพวกเขา และไม่เหมือนกับระบบปัจจุบันของพวกเขา มันจะไม่สูญเสียข้อมูลของพวกเขา เพราะมันจะได้รับการสนับสนุนโดย RDBMS ไม่ใช่ไฟล์แฟลตที่ปลูกเองที่ไม่สม่ำเสมอที่นักพัฒนารายอื่นเคยใช้ ฉันต้องการออกแบบทุกอย่างให้ฉลาดที่สุดเท่าที่จะเป็นไปได้ตั้งแต่ต้นเพราะฉันมีกระดานชนวนที่ว่างเปล่า ความคิดสำหรับระบบนี้ระเบิดออกมาเหมือนดอกไม้ไฟในใจของฉัน และฉันเริ่มออกแบบตาราง—ผู้ติดต่อและบริบทที่หลากหลายสำหรับ CRM, โมดูลการบัญชี, สินค้าคงคลัง, การจัดซื้อ, CMS และการจัดการโครงการ ซึ่งฉันจะลองใช้ในเร็วๆ นี้
ที่ทุกอย่างต้องหยุดชะงัก การพัฒนา และ ประสิทธิภาพ เนื่องจาก...คุณเดาได้แล้วว่าการเพิ่มประสิทธิภาพ
ฉันเห็นว่าออบเจ็กต์ (แสดงเป็นแถวของตาราง) อาจมีความสัมพันธ์ที่แตกต่างกันมากมายในโลกแห่งความเป็นจริง และเราสามารถได้รับประโยชน์จากการติดตามความสัมพันธ์เหล่านี้: เราจะเก็บรักษาข้อมูลเพิ่มเติมและในที่สุดจะทำให้การวิเคราะห์ธุรกิจเป็นไปโดยอัตโนมัติในทุกที่ เมื่อเห็นว่านี่เป็นปัญหาด้านวิศวกรรม ฉันจึงทำสิ่งที่ดูเหมือนเป็นการเพิ่มประสิทธิภาพความยืดหยุ่นของระบบ
ณ จุดนี้ การดูแลใบหน้าของคุณเป็นสิ่งสำคัญ เพราะฉันจะไม่รับผิดชอบหากฝ่ามือของคุณเจ็บ พร้อม? ฉันสร้างตารางสองตาราง: relationship และตารางหนึ่งมีการอ้างอิงคีย์ต่างประเทศ, relationship_type relationship สามารถอ้างถึงสองแถวใดก็ได้ในฐานข้อมูลทั้งหมด และอธิบายลักษณะของความสัมพันธ์ระหว่างพวกเขา
โอ้มนุษย์ ฉันเพิ่งปรับความยืดหยุ่น นั้นให้ เหมาะสมที่สุด
มากเกินไปในความเป็นจริง ตอนนี้ฉันมีปัญหาใหม่แล้ว: ปกติ relationship_type ประเภทหนึ่ง ๆ จะไม่สมเหตุสมผลระหว่างทุกแถวที่ให้มารวมกัน แม้ว่ามันอาจจะสมเหตุสมผลที่ person ได้รับการ employed by ความสัมพันธ์กับ company แต่นั่นก็ไม่เคยมีความหมายเทียบเท่ากับความสัมพันธ์ระหว่าง document สองฉบับ
ได้ไม่มีปัญหา. เราจะเพิ่มสองคอลัมน์ใน relationship_type โดยระบุว่าสามารถใช้ความสัมพันธ์นี้กับตารางใด (คะแนนโบนัสที่นี่ ถ้าคุณเดาว่าฉันคิดเกี่ยวกับการทำให้สิ่งนี้เป็นมาตรฐานโดยการย้ายสองคอลัมน์นั้นไปยังตารางใหม่ที่อ้างอิงถึง relationship_type.id เพื่อให้ความสัมพันธ์ ที่ ใช้ความหมายกับตารางมากกว่าหนึ่งคู่จะไม่มีชื่อตารางซ้ำกัน ท้ายที่สุด ถ้าฉันต้องเปลี่ยนชื่อตารางและลืมอัปเดตในแถวที่เกี่ยวข้องทั้งหมด มันอาจสร้างแมลงได้ เมื่อมองย้อนกลับไป อย่างน้อย แมลงก็จะให้อาหารแก่แมงมุมที่อาศัยอยู่กะโหลกศีรษะของฉัน)
โชคดีที่ฉันหมดสติในพายุที่มีเบาะแสก่อนที่จะเดินทางไกลเกินไปบนเส้นทางนี้ เมื่อฉันตื่นนอน ฉันรู้ว่าฉันได้จัดการ ไม่มากก็น้อย นำตารางที่เกี่ยวกับคีย์ต่างประเทศภายในของ RDBMS มาใช้ใหม่บนตัวมันเอง ปกติแล้วฉันชอบช่วงเวลาที่จบลงด้วยการที่ฉันได้ป่าวประกาศอย่างโอ้อวดว่า “ฉันเป็นเมต้า” แต่น่าเสียดายที่ไม่ใช่หนึ่งในนั้น ลืมไปเลย ว่าไม่สามารถปรับขนาด ได้ เพราะการออกแบบนี้ทำให้ส่วนแบ็คเอนด์ของแอปที่ยังคงความเรียบง่ายของฉัน ที่ซึ่งฐานข้อมูลนั้นแทบไม่มีข้อมูลการทดสอบใดๆ เลย ซึ่งแทบจะใช้ไม่ได้
กลับมาอีกครั้งและมาดูตัวชี้วัดสองรายการจากทั้งหมดที่นี่ หนึ่งคือความยืดหยุ่นซึ่งเป็นเป้าหมายที่ฉันระบุไว้ ในกรณีนี้ การเพิ่มประสิทธิภาพของฉัน ซึ่งเป็นลักษณะทางสถาปัตยกรรม ไม่ได้เกิดขึ้นก่อนกำหนด:
(เราจะพูดถึงเรื่องนี้มากขึ้นในบทความที่ตีพิมพ์ล่าสุดของฉัน วิธีหลีกเลี่ยงคำสาปของการเพิ่มประสิทธิภาพก่อนวัยอันควร) อย่างไรก็ตาม โซลูชันของฉันล้มเหลวอย่างน่าทึ่งเนื่องจากมีความยืดหยุ่น มากเกินไป การวัดความสามารถในการปรับขนาดอื่น ๆ เป็นสิ่งหนึ่งที่ฉันยังไม่ได้พิจารณา แต่สามารถทำลาย อย่างน้อยที่สุดได้อย่างน่าทึ่ง ด้วยความเสียหายหลักประกัน
ถูกต้อง "โอ้"
นี่เป็นบทเรียนที่ทรงพลังสำหรับฉันว่าการเพิ่มประสิทธิภาพจะผิดพลาดได้อย่างไร ความสมบูรณ์แบบของฉันระเบิดออกมาอย่างสมบูรณ์: ความฉลาดของฉันทำให้ฉันสร้างวิธีแก้ปัญหาที่ไม่ฉลาดอย่างเป็นกลางที่สุดที่ฉันเคยทำ
ปรับนิสัยของคุณให้เหมาะสม ไม่ใช่รหัสของคุณ
ขณะที่คุณจับได้ว่าตัวเองกำลังปรับโครงสร้างใหม่ ก่อนที่คุณจะมีต้นแบบที่ใช้งานได้และชุดทดสอบเพื่อยืนยันความถูกต้อง ให้พิจารณาว่าที่ไหนอีกที่คุณสามารถถ่ายทอดแรงกระตุ้นนี้ Sudoku และ Mensa นั้นยอดเยี่ยม แต่บางทีสิ่งที่จะเป็นประโยชน์ต่อโครงการของคุณโดยตรงอาจจะดีกว่า:
- ความปลอดภัย
- ความเสถียรรันไทม์
- ความชัดเจนและสไตล์
- ประสิทธิภาพการเข้ารหัส
- ประสิทธิภาพการทดสอบ
- โปรไฟล์
- ชุดเครื่องมือของคุณ/DE
- แห้ง (อย่าทำซ้ำตัวเอง)
แต่ระวัง: การเพิ่มประสิทธิภาพ heck ออกจากสิ่งใดสิ่งหนึ่งเหล่านี้จะต้องเสียค่าใช้จ่ายของผู้อื่น อย่างน้อยที่สุด ก็ต้องแลกมาด้วยเวลา
ที่นี่เป็นที่ที่ง่ายต่อการดูว่ามีงานศิลปะมากแค่ไหนในการประดิษฐ์โค้ด สำหรับข้อใดข้อหนึ่งข้างต้น ฉันสามารถบอกเล่าเรื่องราวเกี่ยวกับความคิดที่มากเกินไปหรือน้อยเกินไปที่คิดว่าจะเป็นทางเลือกที่ผิด ใครที่กำลังคิดอยู่ในที่นี้ก็เป็นส่วนสำคัญของบริบทเช่นกัน
ตัวอย่างเช่น เกี่ยวกับ DRY: ในงานหนึ่งที่ฉันมี ฉันได้รับโค้ดเบสที่มีข้อความสั่งซ้ำซ้อนอย่างน้อย 80% เพราะเห็นได้ชัดว่าผู้เขียนไม่รู้ว่าจะเขียนฟังก์ชันอย่างไรและเมื่อใด อีก 20% ของรหัสมีความคล้ายคลึงในตัวเองอย่างน่าสับสน
ฉันได้รับมอบหมายให้เพิ่มคุณสมบัติบางอย่างเข้าไป คุณลักษณะดังกล่าวจะต้องทำซ้ำตลอดทั้งโค้ดทั้งหมดจึงจะใช้งานได้ และโค้ดใดๆ ในอนาคตจะต้องคัด ลอกพาสต้า อย่างระมัดระวังเพื่อใช้ประโยชน์จากคุณลักษณะใหม่
เห็นได้ชัดว่าจำเป็นต้องปรับโครงสร้างใหม่เพียงเพื่อความมีสติของตัวเอง (มูลค่าสูง) และสำหรับนักพัฒนาในอนาคต แต่เนื่องจากฉันยังใหม่กับ codebase เลย ฉันจึงเขียนการทดสอบก่อน เพื่อให้แน่ใจว่าการปรับโครงสร้างใหม่ของฉันไม่ได้ทำให้เกิดการถดถอยใดๆ อันที่จริง พวกเขาทำอย่างนั้น: ฉันพบจุดบกพร่องสองตัวระหว่างทางที่ฉันจะไม่สังเกตเห็นในบรรดา gobbledygook ที่สคริปต์สร้างขึ้น
ท้ายที่สุด ฉันคิดว่าฉันทำได้ดีทีเดียว หลังจากการรีแฟคเตอร์ ฉันประทับใจเจ้านายของฉันที่ได้ใช้สิ่งที่ได้รับการพิจารณาว่าเป็นฟีเจอร์ที่ยากด้วยโค้ดง่ายๆ สองสามบรรทัด ยิ่งไปกว่านั้น รหัสโดยรวมมีประสิทธิภาพมากกว่า แต่หลังจากนั้นไม่นานหัวหน้าคนเดิมบอกฉันว่าฉันมาช้าเกินไป และโปรเจ็กต์น่าจะเสร็จสิ้นแล้ว การแปล: ประสิทธิภาพการเข้ารหัสมีความสำคัญสูงกว่า
ระวัง: การเพิ่มประสิทธิภาพ heck จาก [ด้าน] ใด ๆ จะต้องเสียค่าใช้จ่ายของผู้อื่น อย่างน้อยที่สุด ก็ต้องแลกมาด้วยเวลา
ฉันยังคิดว่าฉันเรียนมาถูกทางแล้ว แม้ว่าหัวหน้าของฉันจะไม่ได้ชื่นชมการเพิ่มประสิทธิภาพโค้ดโดยตรงในขณะนั้น หากไม่มีการปรับโครงสร้างและการทดสอบ ฉันคิดว่าต้องใช้เวลานานกว่าจะแก้ไขให้ถูกต้อง กล่าวคือ การมุ่งเน้นที่ความเร็วในการเขียนโค้ดจะขัดขวางการทำงานได้จริง (เฮ้ นั่นคือธีมของเรา!)
เปรียบเทียบสิ่งนี้กับงานบางอย่างที่ฉันทำในโปรเจ็กต์เล็กๆ ของฉัน ในโปรเจ็กต์ ฉันกำลังลองใช้ template engine ใหม่และต้องการสร้างนิสัยที่ดีตั้งแต่เริ่มต้น แม้ว่าการลองใช้ template engine ใหม่จะไม่ใช่เป้าหมายสุดท้ายของโปรเจ็กต์
ทันทีที่ฉันสังเกตเห็นว่าสองสามช่วงตึกที่ฉันเพิ่มเข้าไปมีความคล้ายคลึงกันมาก และยิ่งไปกว่านั้น แต่ละบล็อกจำเป็นต้องอ้างถึงตัวแปรเดียวกันสามครั้ง ระฆัง DRY ก็ดับลงในหัวของฉัน และฉันก็ออกเดินทางเพื่อค้นหาสิ่งที่ถูกต้อง วิธีทำในสิ่งที่ฉันพยายามจะทำกับเครื่องมือเทมเพลตนี้
ปรากฏว่าหลังจากสองสามชั่วโมงของการดีบักอย่างไร้ผล ในปัจจุบันนี้ไม่สามารถทำได้ด้วยเครื่องมือเทมเพลตในแบบที่ฉันจินตนาการ ไม่เพียงแต่ไม่มีสารละลายดราย ที่สมบูรณ์แบบ เท่านั้น ไม่มีวิธีแก้ ปัญหา แบบแห้งเลย!
ฉันพยายามปรับค่าหนึ่งของฉันให้เหมาะสมที่สุด ฉันทำให้ประสิทธิภาพการเขียนโค้ดและความสุขของฉันตกรางลงโดยสิ้นเชิง เพราะทางอ้อมนี้ทำให้โปรเจ็กต์ของฉันต้องสูญเสียความคืบหน้าในวันนั้น
ถึงอย่างนั้นฉันผิดไปทั้งหมดหรือเปล่า? บางครั้งก็คุ้มค่าแก่การลงทุน โดยเฉพาะอย่างยิ่งกับบริบททางเทคโนโลยีใหม่ เพื่อทำความรู้จักแนวทางปฏิบัติที่ดีที่สุดตั้งแต่เนิ่นๆ แทนที่จะเรียนรู้ในภายหลัง โค้ดที่เขียนใหม่น้อยลงและเลิกทำนิสัยแย่ๆ ใช่ไหม
ไม่ ฉันคิดว่ามันไม่ฉลาดแม้แต่จะหาทางลดความซ้ำซ้อนในโค้ดของฉัน ตรงกันข้ามกับทัศนคติของฉันในเรื่องเล็กน้อยก่อนหน้านี้ เหตุผลก็คือบริบทนั้นคือทุกอย่าง: ฉันกำลังสำรวจเทคโนโลยีชิ้นใหม่ในโครงการเล่นเล็ก ๆ ที่ไม่ได้ลงหลักปักฐานในระยะยาว การเพิ่มบรรทัดและการทำซ้ำสองสามบรรทัดจะไม่ทำร้ายใคร แต่การสูญเสียโฟกัสทำร้ายฉันและโครงการของฉัน
เดี๋ยวนะ การแสวงหาแนวทางปฏิบัติที่ดีที่สุดอาจเป็นนิสัยที่ไม่ดีได้หรือ บางครั้ง. หากเป้าหมาย หลัก ของฉันคือการเรียนรู้กลไกใหม่ หรือการเรียนรู้โดยทั่วไป นั่นก็เป็นเวลาที่ดีแล้ว: การซ่อมแซม การค้นหาขีดจำกัด การค้นหาคุณสมบัติที่ไม่เกี่ยวข้องและคำสั่งต่างๆ ผ่านการค้นคว้า แต่ฉันลืมไปว่านี่ไม่ใช่เป้าหมายหลักของฉัน และทำให้ฉันต้องเสียค่าใช้จ่าย
มันเป็นศิลปะอย่างที่ฉันพูด และการพัฒนาของศิลปะนั้นได้ประโยชน์จากการเตือนว่า Don't do it . อย่างน้อยก็ทำให้คุณต้องพิจารณาว่าค่านิยมใดที่กำลังเล่นอยู่ในขณะที่คุณทำงาน และค่าใดที่สำคัญที่สุดสำหรับ คุณ ในบริบท ของคุณ
แล้วกฎข้อที่สองล่ะ? เมื่อ ใดที่เราสามารถเพิ่มประสิทธิภาพได้จริง
2. Don't Do It Yet : มีคนทำไปแล้ว
ตกลง ไม่ว่าโดยคุณหรือโดยคนอื่น คุณพบว่าสถาปัตยกรรมของคุณได้รับการตั้งค่าแล้ว โฟลว์ข้อมูลได้รับการพิจารณาและจัดทำเป็นเอกสารแล้ว และได้เวลาเขียนโค้ดแล้ว
เอา ล่ะ อย่าเพิ่งทำ ขั้นต่อไป: อย่าเพิ่งเขียนโค้ดเลย
สิ่งนี้เองอาจมีกลิ่นเหมือนการเพิ่มประสิทธิภาพก่อนเวลาอันควร แต่เป็นข้อยกเว้นที่สำคัญ ทำไม? เพื่อหลีกเลี่ยง NIHS ที่น่ากลัวหรือ "ไม่ได้ประดิษฐ์ที่นี่" ซินโดรม—สมมติว่าลำดับความสำคัญของคุณรวมถึงประสิทธิภาพของโค้ดและการลดเวลาในการพัฒนาให้น้อยที่สุด ถ้าไม่ หากเป้าหมายของคุณคือการเรียนรู้โดยสมบูรณ์ คุณสามารถข้ามส่วนถัดไปนี้ได้
แม้ว่าจะเป็นไปได้ที่ผู้คนจะคิดค้นล้อสี่เหลี่ยมขึ้นมาใหม่จากความโอหัง แต่ฉันเชื่อว่าคนที่ซื่อสัตย์และถ่อมตน เช่นคุณและฉัน สามารถทำผิดพลาดนี้ได้เพียงแต่ไม่รู้ตัวเลือกทั้งหมดที่มีให้เรา การรู้ทุกตัวเลือกของ API และเครื่องมือทุกตัวในสแต็กของคุณและดูแลให้ดีที่สุดในขณะที่เติบโตและพัฒนานั้นเป็นงานที่ต้องทำอย่างแน่นอน
แต่การให้เวลานี้เป็นสิ่งที่ทำให้คุณเป็นผู้เชี่ยวชาญและป้องกันไม่ให้คุณเป็นบุคคลที่หนึ่งพันล้านใน CodeSOD ที่จะถูกสาปและล้อเลียนสำหรับเส้นทางแห่งความหายนะที่ทิ้งไว้โดยการใช้เครื่องคิดเลขวันที่เวลาหรือเครื่องมือควบคุมสตริงที่น่าสนใจ
(จุดแตกต่างที่ดีของรูปแบบทั่วไปนี้คือ Java Calendar API แบบเก่า แต่ได้รับการแก้ไขแล้ว)
ตรวจสอบไลบรารีมาตรฐานของคุณ ตรวจสอบระบบนิเวศของกรอบงานของคุณ ตรวจสอบ FOSS ที่แก้ปัญหาของคุณได้แล้ว
เป็นไปได้ว่าแนวคิดที่คุณกำลังติดต่อด้วยมีชื่อที่ค่อนข้างธรรมดาและเป็นที่รู้จักกันดี ดังนั้นการค้นหาทางอินเทอร์เน็ตอย่างรวดเร็วจะช่วยคุณประหยัดเวลาได้มาก
ตัวอย่างเช่น เมื่อเร็วๆ นี้ ฉันกำลังเตรียมวิเคราะห์กลยุทธ์ AI สำหรับเกมกระดาน ฉันตื่นขึ้นมาในเช้าวันหนึ่งโดยตระหนักว่าการวิเคราะห์ที่ฉันกำลังวางแผนนั้นสามารถดำเนินการตามลำดับความสำคัญได้อย่างมีประสิทธิภาพมากขึ้น หากฉันเพียงแค่ใช้แนวคิดเชิงผสมผสานบางอย่างที่ฉันจำได้ ตอนนี้ฉันไม่สนใจที่จะหาอัลกอริทึมสำหรับแนวคิดนี้ ฉันจึงรู้ชื่อที่ถูกต้องในการค้นหาอยู่แล้ว อย่างไรก็ตาม ฉันพบว่าหลังจากค้นคว้าประมาณ 50 นาทีและลองใช้โค้ดเบื้องต้น ฉันไม่สามารถเปลี่ยนรหัสเทียมที่เสร็จสิ้นไปแล้วครึ่งหนึ่งที่ฉันพบว่านำไปใช้งานได้อย่างถูกต้อง (คุณเชื่อไหมว่ามีบล็อกโพสต์อยู่ที่นั่นซึ่งผู้เขียนถือว่าเอาท์พุตอัลกอริธึมที่ไม่ถูกต้อง ใช้อัลกอริธึมไม่ถูกต้องเพื่อให้ตรงกับสมมติฐาน ผู้แสดงความคิดเห็นชี้ให้เห็น และหลายปีต่อมา ก็ยังคงไม่ได้รับการแก้ไข) ณ จุดนั้น ชายามเช้าของฉัน เข้ามา และฉันค้นหา [name of concept] [my programming language] 30 วินาทีต่อมา ฉันได้พิสูจน์แล้วว่าโค้ดถูกต้องจาก GitHub และกำลังก้าวไปสู่สิ่งที่ฉันต้องการจะทำจริงๆ แค่การเฉพาะเจาะจงและรวมภาษาเข้าไปด้วย แทนที่จะคิดว่าฉันจะต้องปรับใช้มันเอง มันหมายถึงทุกอย่าง
ถึงเวลาออกแบบโครงสร้างข้อมูลของคุณและใช้อัลกอริทึมของคุณ
…อีกครั้ง อย่าเล่นรหัสกอล์ฟ จัดลำดับความสำคัญของความถูกต้องและความชัดเจนในโครงการในโลกแห่งความเป็นจริง
ตกลง คุณได้ดูไปแล้ว และไม่มีอะไรที่แก้ปัญหาของคุณได้อยู่แล้วใน toolchain ของคุณ หรือได้รับอนุญาตอย่างเสรีบนเว็บ คุณเปิดตัวของคุณเอง
ไม่มีปัญหา. คำแนะนำนั้นง่ายในลำดับนี้:
- ออกแบบเพื่อให้ง่ายต่อการอธิบายให้โปรแกรมเมอร์มือใหม่เข้าใจ
- เขียนแบบทดสอบที่เหมาะกับความคาดหวังที่เกิดจากการออกแบบนั้น
- เขียนโค้ดของคุณเพื่อให้โปรแกรมเมอร์มือใหม่สามารถรวบรวมการออกแบบจากมันได้อย่างง่ายดาย
เรียบง่าย แต่บางทีก็ยากที่จะทำตาม นี่คือที่มาของนิสัยการเขียนโค้ดและกลิ่นของโค้ด รวมถึงงานศิลปะ งานฝีมือ และความสง่างาม เห็นได้ชัดว่ามีแง่มุมทางวิศวกรรมในสิ่งที่คุณทำในตอนนี้ แต่อย่าเล่นรหัสกอล์ฟ จัดลำดับความสำคัญของความถูกต้องและความชัดเจนในโครงการในโลกแห่งความเป็นจริง
หากคุณชอบวิดีโอ นี่คือหนึ่งในผู้ที่ทำตามขั้นตอนข้างต้น ไม่มากก็น้อย สำหรับผู้ที่ไม่ชอบวิดีโอ ฉันจะสรุป: เป็นการทดสอบการเข้ารหัสอัลกอริทึมในการสัมภาษณ์งานของ Google ขั้นแรกผู้ให้สัมภาษณ์จะออกแบบอัลกอริทึมในลักษณะที่ง่ายต่อการสื่อสาร ก่อนที่จะเขียนโค้ดใด ๆ มีตัวอย่างผลลัพธ์ที่คาดหวังจากการออกแบบการทำงาน จากนั้นรหัสจะตามมาตามธรรมชาติ
สำหรับการทดสอบเอง ฉันรู้ว่าในบางแวดวง การพัฒนาที่ขับเคลื่อนด้วยการทดสอบอาจเป็นที่ถกเถียงกัน ฉันคิดว่าเหตุผลส่วนหนึ่งก็คือมันสามารถเกินกำลังได้ ปฏิบัติตามอย่างเคร่งครัดจนถึงจุดที่ต้องเสียสละเวลาในการพัฒนา (อีกครั้ง การยิงตัวเองด้วยการพยายามปรับให้เหมาะสมแม้แต่ตัวแปรเดียวมากเกินไปตั้งแต่เริ่มต้น) แม้แต่เคนท์ เบ็ค ก็ไม่ได้ใช้ TDD ถึงจุดสุดโต่งเช่นนี้ และเขาก็คิดค้นโปรแกรมสุดขั้วและเขียนหนังสือบน TDD ดังนั้นให้เริ่มต้นด้วยสิ่งง่ายๆ เพื่อให้แน่ใจว่าผลลัพธ์ของคุณถูกต้อง ท้ายที่สุดคุณจะทำด้วยตนเองหลังจากเข้ารหัสใช่ไหม (ขออภัยถ้าคุณเป็นโปรแกรมเมอร์ร็อคสตาร์ที่คุณไม่ได้เรียกใช้โค้ดของคุณหลังจากเขียนครั้งแรก ในกรณีนี้ คุณอาจลองพิจารณาปล่อยให้ผู้ดูแลโค้ดของคุณในอนาคตมีการทดสอบเพียงเพื่อให้คุณรู้ว่า พวกเขา จะไม่ ทำลายการใช้งานที่ยอดเยี่ยมของคุณ) ดังนั้นแทนที่จะทำคู่มือ ความแตกต่างของภาพ ด้วยการทดสอบ คุณได้ปล่อยให้คอมพิวเตอร์ทำงานนั้นแทนคุณแล้ว
ในระหว่างกระบวนการเชิงกลไกของการนำอัลกอริทึมและโครงสร้างข้อมูลของคุณไปใช้ ให้หลีกเลี่ยงการปรับให้เหมาะสมทีละบรรทัด และอย่า คิด แม้แต่จะใช้ภาษาภายนอกระดับล่างแบบกำหนดเอง (การประกอบหากคุณกำลังเข้ารหัสในภาษา C, C ถ้าคุณ กำลังเขียนโค้ดใน Perl เป็นต้น) ณ จุดนี้ เหตุผลง่าย ๆ คือ หากอัลกอริทึมของคุณถูกแทนที่ทั้งหมด และคุณจะไม่ทราบจนกว่าจะถึงกระบวนการในภายหลังว่าจำเป็นหรือไม่ ความพยายามในการเพิ่มประสิทธิภาพระดับต่ำของคุณจะไม่มีผลในท้ายที่สุด
ตัวอย่าง ECMAScript
ในเว็บไซต์ตรวจสอบโค้ดชุมชนที่ยอดเยี่ยม exercism.io ฉันเพิ่งพบแบบฝึกหัดที่แนะนำอย่างชัดเจนว่าควรพยายามเพิ่มประสิทธิภาพสำหรับการขจัดข้อมูลซ้ำซ้อนหรือเพื่อความชัดเจน ฉันปรับให้เหมาะสมสำหรับการขจัดข้อมูลซ้ำซ้อน เพื่อแสดงให้เห็นว่าสิ่งไร้สาระจะเกิดขึ้นได้อย่างไรหากคุณใช้ DRY ซึ่งเป็นแนวคิดในการเขียนโค้ดที่เป็นประโยชน์อย่างอื่นดังที่ได้กล่าวไว้ข้างต้น ไกลเกินไป นี่คือลักษณะรหัสของฉัน:
const zeroPhrase = "No more"; const wallPhrase = " on the wall"; const standardizeNumber = number => { if (number === 0) { return zeroPhrase; } return '' + number; } const bottlePhrase = number => { const possibleS = (number === 1) ? '' : 's'; return standardizeNumber(number) + " bottle" + possibleS + " of beer"; } export default class Beer { static verse(number) { const nextNumber = (number === 0) ? 99 : (number - 1); const thisBottlePhrase = bottlePhrase(number); const nextBottlePhrase = bottlePhrase(nextNumber); let phrase = thisBottlePhrase + wallPhrase + ", " + thisBottlePhrase.toLowerCase() + ".\n"; if (number === 0) { phrase += "Go to the store and buy some more"; } else { const bottleReference = (number === 1) ? "it" : "one"; phrase += "Take " + bottleReference + " down and pass it around"; } return phrase + ", " + nextBottlePhrase.toLowerCase() + wallPhrase + ".\n"; } static sing(start = 99, end = 0) { return Array.from(Array(start - end + 1).keys()).map(offset => { return this.verse(start - offset); }).join('\n'); } } แทบไม่มีการซ้ำซ้อนของสตริงเลย! โดยการเขียนแบบนี้ ฉันได้ใช้รูปแบบการบีบอัดข้อความสำหรับเพลงเบียร์ (แต่สำหรับเพลงเบียร์ เท่านั้น ) ด้วยตนเอง มีประโยชน์อะไรกันแน่? สมมติว่าคุณต้องการร้องเพลงเกี่ยวกับการดื่มเบียร์จากกระป๋องแทนขวด ฉันสามารถทำได้โดยเปลี่ยน อินสแตนซ์ bottle เดียวเป็น can
ดี!
…ขวา?
ไม่ เพราะจากนั้นการทดสอบทั้งหมดก็จะพัง ตกลง ง่ายที่จะแก้ไข: เราจะทำการค้นหาและเปลี่ยน bottle ในข้อมูลจำเพาะการทดสอบหน่วย และนั่นก็ง่ายพอๆ กับการทำสิ่งนั้นกับตัวโค้ดเองตั้งแต่แรก และมีความเสี่ยงเช่นเดียวกันกับการทำลายสิ่งต่าง ๆ โดยไม่ได้ตั้งใจ
ในขณะเดียวกัน ตัวแปรของฉันจะถูกตั้งชื่ออย่างแปลกๆ ในภายหลัง โดยที่สิ่งต่าง ๆ เช่น bottlePhrase ไม่มีอะไรเกี่ยวข้องกับ ขวด เลย วิธีเดียวที่จะหลีกเลี่ยงสิ่งนี้คือต้องคาดการณ์ล่วงหน้าถึงประเภทของการเปลี่ยนแปลงที่จะทำและใช้คำทั่วไป เช่น vessel หรือ container แทน bottle ในชื่อตัวแปรของฉัน
ปัญญาในการพิสูจน์อนาคตในลักษณะนี้ค่อนข้างน่าสงสัย อัตราต่อรองที่คุณต้องการเปลี่ยนแปลงคืออะไร? และถ้าคุณทำสิ่งที่คุณเปลี่ยนจะสะดวกหรือไม่? ในตัวอย่าง bottlePhrase จะเป็นอย่างไรถ้าคุณต้องการแปลเป็นภาษาที่มีรูปแบบพหูพจน์มากกว่าสองรูปแบบ ถูกต้อง เวลาปรับโครงสร้างใหม่ และโค้ดอาจดูแย่กว่าเดิมในภายหลัง
แต่เมื่อความต้องการของ คุณ เปลี่ยนไป และคุณไม่ ได้ เพียงแค่พยายามคาดการณ์เท่านั้น อาจถึงเวลาที่ต้องปรับโครงสร้างใหม่ หรือบางทีคุณอาจจะยังเอามันออกไป: คุณจะเพิ่มประเภทเรือหรือโลคัลไลเซชันกี่แบบตามความเป็นจริง? อย่างไรก็ตาม เมื่อคุณต้องการปรับสมดุลการขจัดข้อมูลซ้ำซ้อนด้วยความชัดเจน คุณควรรับชมการสาธิตนี้โดย Katrina Owen
กลับไปที่ตัวอย่างที่น่าเกลียดของฉันเอง ไม่จำเป็นต้องพูด ประโยชน์ของการขจัดข้อมูลซ้ำซ้อนไม่ได้เกิดขึ้นจริงที่นี่มากขนาดนั้น ในขณะเดียวกันค่าใช้จ่ายคืออะไร?
นอกจากจะใช้เวลาในการเขียนนานขึ้นตั้งแต่แรก ตอนนี้การอ่าน แก้จุดบกพร่อง และบำรุงรักษาก็ค่อนข้างเป็นเรื่องเล็กน้อย ลองนึกภาพระดับความสามารถในการอ่านที่อนุญาตให้ทำซ้ำได้ในระดับปานกลาง ตัวอย่างเช่น การสะกดคำแต่ละคำจากสี่ข้อที่แตกต่างกัน
แต่เรายังไม่ได้ปรับให้เหมาะสม!
ตอนนี้อัลกอริทึมของคุณได้รับการใช้งานแล้ว และคุณได้พิสูจน์แล้วว่าผลลัพธ์นั้นถูกต้อง ขอแสดงความยินดีด้วย! คุณมีพื้นฐาน!
ในที่สุดก็ถึงเวลา…เพิ่มประสิทธิภาพใช่ไหม ไม่นะ อย่าเพิ่งทำ ถึงเวลาที่จะใช้พื้นฐานของคุณและสร้าง เกณฑ์มาตรฐาน ที่ดี กำหนดเกณฑ์สำหรับความคาดหวังของคุณเกี่ยวกับเรื่องนี้และติดไว้ในชุดทดสอบของคุณ จากนั้นหากมีบางอย่างทำให้โค้ดนี้ทำงานช้าลง แม้ว่าจะยังใช้ได้อยู่ก็ตาม คุณจะรู้ก่อนที่โค้ดจะออกไป
ยังคงระงับการเพิ่มประสิทธิภาพ จนกว่าคุณจะได้รับประสบการณ์ผู้ใช้ที่เกี่ยวข้องทั้งหมด ก่อนหน้านั้น คุณอาจกำหนดเป้าหมายส่วนอื่นของโค้ดที่ต่างไปจากเดิมอย่างสิ้นเชิง
ดำเนินการแอปของคุณให้เสร็จ (หรือส่วนประกอบ) หากคุณยังไม่ได้ดำเนินการ ให้ตั้งค่าพื้นฐานเกณฑ์มาตรฐานอัลกอริทึมทั้งหมดของคุณ
เมื่อดำเนินการเสร็จแล้ว นี่เป็นเวลาที่ดีในการสร้างและเปรียบเทียบการทดสอบแบบ end-to-end ที่ครอบคลุมสถานการณ์การใช้งานจริงโดยทั่วไปในระบบของคุณ
บางทีคุณอาจพบว่าทุกอย่างเรียบร้อยดี
หรือบางทีคุณอาจกำหนดไว้แล้วว่าในบริบทในชีวิตจริง มีบางอย่างที่ช้าเกินไปหรือใช้หน่วยความจำมากเกินไป
ตกลง ตอนนี้ คุณสามารถเพิ่มประสิทธิภาพได้
มีทางเดียวเท่านั้นที่จะมีเป้าหมายเกี่ยวกับเรื่องนี้ ได้เวลาแยกกราฟเปลวไฟและเครื่องมือทำโปรไฟล์อื่นๆ ออกแล้ว วิศวกรที่มีประสบการณ์อาจจะหรืออาจจะไม่เดาได้บ่อยกว่ามือใหม่ แต่นั่นไม่ใช่ประเด็น: วิธีเดียวที่จะทราบได้อย่างแน่นอนคือการทำโปรไฟล์ นี่เป็นสิ่งแรกที่ต้องทำเสมอในกระบวนการเพิ่มประสิทธิภาพโค้ดเพื่อประสิทธิภาพ
คุณสามารถสร้างโปรไฟล์ระหว่างการทดสอบแบบ end-to-end ที่กำหนด เพื่อดูว่าสิ่งใดจะสร้างผลกระทบได้มากที่สุด (และภายหลังหลังจากปรับใช้ การตรวจสอบรูปแบบการใช้งานเป็นวิธีที่ยอดเยี่ยมในการติดตามว่าแง่มุมใดของระบบของคุณมีความเกี่ยวข้องมากที่สุดสำหรับการวัดในอนาคต)
โปรดทราบว่าคุณไม่ได้พยายามใช้ตัวสร้างโปรไฟล์จนเต็ม—คุณกำลังมองหาการทำโปรไฟล์ระดับฟังก์ชันมากกว่าการทำโปรไฟล์ระดับคำสั่ง โดยทั่วไป เนื่องจากเป้าหมายของคุณ ณ จุดนี้เป็นเพียงการค้นหาว่า อัลกอริธึม ใดที่เป็นคอขวด .
เมื่อคุณใช้การทำโปรไฟล์เพื่อระบุปัญหาคอขวดของระบบแล้ว ตอนนี้คุณสามารถพยายามเพิ่มประสิทธิภาพได้อย่างแท้จริง โดยมั่นใจว่าการเพิ่มประสิทธิภาพของคุณนั้นคุ้มค่าที่จะทำ คุณยังสามารถพิสูจน์ได้ว่าความพยายามของคุณนั้นได้ผล (หรือไม่ได้ผล) ด้วยเกณฑ์มาตรฐานที่คุณทำไปตลอดทาง
เทคนิคโดยรวม
อันดับแรก อย่าลืมอยู่ในระดับสูงให้นานที่สุด:
เธอรู้รึเปล่า? เคล็ดลับการเพิ่มประสิทธิภาพสากลขั้นสูงสุด นำไปใช้ในทุกกรณี:
– Lars Doucet (@larsiusprime) วันที่ 30 มีนาคม 2017
- วาดของน้อยลง
- อัพเดทน้อยลง
ที่ระดับอัลกอริธึมทั้งหมด เทคนิคหนึ่งคือการลดกำลัง ในกรณีของการลดลูปเป็นสูตร ให้คำนึงถึงการแสดงความคิดเห็น ไม่ใช่ทุกคนที่รู้หรือจำสูตรการรวมกันทั้งหมด นอกจากนี้ โปรดใช้ความระมัดระวังในการใช้คณิตศาสตร์: บางครั้งสิ่งที่คุณคิดว่าอาจเป็นการลดความเข้มแข็งอาจไม่ใช่ในท้ายที่สุด ตัวอย่างเช่น สมมติว่า x * (y + z) มีความหมายอัลกอริทึมที่ชัดเจน หากสมองของคุณได้รับการฝึกฝนมาแล้ว ไม่ว่าจะด้วยเหตุผลใดก็ตาม เพื่อยกเลิกการจัดกลุ่มคำที่เหมือนกันโดยอัตโนมัติ คุณอาจถูกล่อลวงให้เขียนใหม่เป็น x * y + x * z ประการหนึ่ง สิ่งนี้ทำให้เกิดอุปสรรคระหว่างผู้อ่านกับความหมายอัลกอริทึมที่ชัดเจนที่เคยมี (ที่แย่กว่านั้น คือ จริง ๆ แล้วมีประสิทธิภาพ น้อยลง เนื่องจากต้องใช้การคูณเพิ่มเติม มันเหมือนกับการคลายห่วงแค่ผูกกางเกงของมัน) ไม่ว่าในกรณีใด การจดบันทึกสั้นๆ เกี่ยวกับความตั้งใจของคุณจะช่วยได้มาก และอาจช่วยให้คุณเห็น ข้อผิดพลาดของตัวเองก่อนที่คุณจะกระทำมัน
ไม่ว่าคุณจะใช้สูตรหรือเพียงแค่แทนที่อัลกอริธึมแบบวนซ้ำด้วยอัลกอริธึมแบบวนซ้ำอื่น คุณก็พร้อมที่จะวัดความแตกต่างแล้ว
แต่บางทีคุณอาจได้รับประสิทธิภาพที่ดีขึ้นเพียงแค่เปลี่ยนโครงสร้างข้อมูลของคุณ ให้ความรู้เกี่ยวกับความแตกต่างของประสิทธิภาพระหว่างการดำเนินการต่างๆ ที่คุณต้องทำกับโครงสร้างที่คุณกำลังใช้ และในทางเลือกอื่นๆ บางทีแฮชอาจดูยุ่งยากกว่าเล็กน้อยในการทำงานภายในบริบทของคุณ แต่เวลาในการค้นหาที่เหนือกว่านั้นคุ้มค่ากว่าอาร์เรย์หรือไม่ นี่คือประเภทของการแลกเปลี่ยนซึ่งขึ้นอยู่กับคุณที่จะตัดสินใจ
คุณอาจสังเกตเห็นว่าสิ่งนี้ทำให้รู้ว่าอัลกอริทึมใดที่กำลังดำเนินการในนามของคุณเมื่อคุณเรียกใช้ฟังก์ชันอำนวยความสะดวก ในที่สุดมันก็เหมือนกับการลดความแข็งแกร่งในที่สุด และการรู้ว่าไลบรารีของผู้จำหน่ายของคุณกำลังทำอะไรอยู่เบื้องหลังเป็นสิ่งสำคัญไม่เพียงแต่สำหรับประสิทธิภาพเท่านั้น แต่ยังรวมถึงการหลีกเลี่ยงจุดบกพร่องที่ไม่ได้ตั้งใจด้วย
การเพิ่มประสิทธิภาพไมโคร
ตกลง ฟังก์ชันการทำงานของระบบของคุณเสร็จเรียบร้อยแล้ว แต่จากมุมมองของ UX ประสิทธิภาพอาจปรับแต่งได้อีกเล็กน้อย สมมติว่าคุณได้ทำทุกอย่างที่ทำได้ในระดับที่สูงขึ้นแล้ว ก็ถึงเวลา พิจารณา ถึงการเพิ่มประสิทธิภาพที่เราหลีกเลี่ยงมาตลอดจนถึงตอนนี้ พิจารณา เพราะระดับของการเพิ่มประสิทธิภาพนี้ยังคงเป็นการประนีประนอมกับความชัดเจนและการบำรุงรักษา แต่คุณได้ตัดสินใจว่าถึงเวลาแล้ว ดังนั้น ดำเนินการต่อด้วยการทำโปรไฟล์ระดับคำสั่ง ตอนนี้คุณอยู่ในบริบทของทั้งระบบแล้ว ซึ่งมันมีความสำคัญจริงๆ
เช่นเดียวกับไลบรารีที่คุณใช้ ชั่วโมงวิศวกรรมนับไม่ถ้วนได้ทุ่มเทให้กับคุณในระดับคอมไพเลอร์หรือล่าม (ท้ายที่สุด การเพิ่มประสิทธิภาพคอมไพเลอร์และการสร้างโค้ดเป็นหัวข้อใหญ่ในตัวเอง) สิ่งนี้เป็นจริงแม้กระทั่งในระดับโปรเซสเซอร์ การพยายามเพิ่มประสิทธิภาพโค้ดโดยไม่ทราบว่าเกิดอะไรขึ้นในระดับต่ำสุดก็เหมือนกับการคิดว่าระบบขับเคลื่อนสี่ล้อหมายความว่ารถของคุณสามารถหยุดได้ง่ายขึ้นเช่นกัน
เป็นการยากที่จะให้คำแนะนำทั่วไปที่ดีไปกว่านั้น เพราะมันขึ้นอยู่กับกลุ่มเทคโนโลยีของคุณและสิ่งที่ผู้สร้างโปรไฟล์ของคุณชี้ไปที่ แต่เนื่องจากคุณกำลังวัด คุณอยู่ในตำแหน่งที่ยอดเยี่ยมแล้วที่จะขอความช่วยเหลือ หากวิธีแก้ปัญหาไม่นำเสนอตัวเองจากบริบทของปัญหาอย่างเป็นธรรมชาติและโดยสัญชาตญาณ (การนอนหลับและใช้เวลาคิดเรื่องอื่นก็ช่วยได้เช่นกัน)
ณ จุดนี้ ขึ้นอยู่กับบริบทและข้อกำหนดในการปรับขนาด Jeff Atwood อาจแนะนำเพียงเพิ่มฮาร์ดแวร์ ซึ่งอาจถูกกว่าเวลาของนักพัฒนาซอฟต์แวร์
บางทีคุณอาจไม่ได้ไปเส้นทางนั้น ในกรณีดังกล่าว อาจช่วยในการสำรวจหมวดหมู่ต่างๆ ของเทคนิคการเพิ่มประสิทธิภาพโค้ด:
- เก็บเอาไว้
- บิตแฮ็กและเฉพาะสภาพแวดล้อม 64 บิต
- การเพิ่มประสิทธิภาพลูป
- การเพิ่มประสิทธิภาพลำดับชั้นของหน่วยความจำ
โดยเฉพาะอย่างยิ่ง:
- เคล็ดลับการเพิ่มประสิทธิภาพโค้ดใน C และ C++
- เคล็ดลับการเพิ่มประสิทธิภาพโค้ดใน Java
- เพิ่มประสิทธิภาพการใช้งาน CPU ใน .NET
- ASP.NET เว็บฟาร์มแคช
- การปรับแต่งฐานข้อมูล SQL หรือการปรับแต่ง Microsoft SQL Server โดยเฉพาะ
- การเล่นของสกาล่าสเกล! กรอบ
- การเพิ่มประสิทธิภาพขั้นสูงของ WordPress
- การเพิ่มประสิทธิภาพโค้ดด้วย JavaScript ต้นแบบและขอบเขตเชน
- เพิ่มประสิทธิภาพการตอบสนอง
- ประสิทธิภาพแอนิเมชั่น iOS
- เคล็ดลับประสิทธิภาพของ Android
อย่างไรก็ตาม ฉันมีสิ่งที่ ไม่ควรทำ เพิ่มเติม สำหรับคุณ:
อย่าใช้ตัวแปรซ้ำเพื่อวัตถุประสงค์ที่แตกต่างกันหลายประการ ในแง่ของการบำรุงรักษาก็เหมือนกับการใช้รถที่ไม่มีน้ำมัน เฉพาะในสถานการณ์ที่ฝังแน่นที่สุดเท่านั้นที่สิ่งนี้สมเหตุสมผล และแม้แต่ในกรณีเหล่านั้น ฉันก็เถียงว่ามันไม่สมเหตุสมผลแล้ว เป็นหน้าที่ของคอมไพเลอร์ในการจัดระเบียบ ทำด้วยตัวเอง จากนั้นย้ายโค้ดหนึ่งบรรทัด แสดงว่าคุณได้แนะนำจุดบกพร่อง ภาพลวงตาของการบันทึกความทรงจำมีค่าสำหรับคุณหรือไม่?
อย่าใช้มาโครและฟังก์ชันอินไลน์โดยไม่ทราบสาเหตุ ใช่ ค่าใช้จ่ายในการเรียกใช้ฟังก์ชันถือเป็นค่าใช้จ่าย แต่การหลีกเลี่ยงมักจะทำให้โค้ดของคุณดีบักยากขึ้น และบางครั้งก็ทำให้โค้ดช้าลง ใช้เทคนิคนี้ทุกที่ เพียงเพราะเป็นความคิดที่ดี นานๆ ครั้งเป็นตัวอย่างของค้อนทองคำ
อย่าคลายลูปด้วยมือ อีกครั้ง รูปแบบของการเพิ่มประสิทธิภาพลูปนี้มักจะได้รับการปรับให้เหมาะสมที่สุดโดยกระบวนการอัตโนมัติ เช่น การคอมไพล์ ไม่ใช่โดยการเสียสละความสามารถในการอ่านโค้ดของคุณ
ประชดในสองตัวอย่างการเพิ่มประสิทธิภาพโค้ดสุดท้ายคือ พวกเขาสามารถป้องกันประสิทธิภาพได้จริง แน่นอน เนื่องจากคุณกำลังทำการวัดประสิทธิภาพ คุณจึงสามารถพิสูจน์หรือหักล้างสิ่งนั้นสำหรับโค้ดของคุณโดยเฉพาะได้ แต่แม้ว่าคุณจะเห็นการปรับปรุงประสิทธิภาพ ให้กลับไปที่ด้านศิลปะ และดูว่าการเพิ่มขึ้นนั้นคุ้มกับการสูญเสียในด้านความสามารถในการอ่านและการบำรุงรักษาหรือไม่
เป็นของคุณ: การเพิ่มประสิทธิภาพที่เหมาะสมที่สุด
การพยายามเพิ่มประสิทธิภาพประสิทธิภาพอาจเป็นประโยชน์ อย่างไรก็ตาม บ่อยครั้งกว่าที่ทำเสร็จก่อนเวลาอันควร มาพร้อมกับบทสวดของผลข้างเคียงที่ไม่ดี และที่น่าขันที่สุดคือนำไปสู่ประสิทธิภาพที่แย่ลง ฉันหวังว่าคุณจะรู้สึกซาบซึ้งในศิลปะและวิทยาศาสตร์ของการเพิ่มประสิทธิภาพ และที่สำคัญที่สุดคือบริบทที่เหมาะสม
ฉันยินดีหากสิ่งนี้ช่วยให้เราละทิ้งแนวคิดในการเขียนโค้ดที่สมบูรณ์แบบตั้งแต่เริ่มต้นและเขียนโค้ดที่ถูกต้องแทนได้ เราต้องจำไว้ว่าต้องปรับให้เหมาะสมจากบนลงล่าง พิสูจน์ว่าคอขวดอยู่ตรงไหน และวัดผลก่อนและหลังการแก้ไข นั่นคือกลยุทธ์ที่เหมาะสมและเหมาะสมที่สุดในการเพิ่มประสิทธิภาพการเพิ่มประสิทธิภาพ ขอให้โชคดี

