ทำไมนักพัฒนาหลายคนเชื่อว่าประสิทธิภาพการอ่านและการบำรุงรักษาไม่สามารถอยู่ร่วมกันได้?


34

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

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

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


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

7
หมู่ คุณควรเริ่มต้นด้วยการสนับสนุนแถลงการณ์ของคุณว่านักพัฒนาหลายคนยืนยันว่าประสิทธิภาพนั้นนำไปสู่ความไร้ประสิทธิภาพ
Peter Taylor

2
SK-logic: ในความคิดของฉันเป็นหนึ่งในส่วนที่ดีที่สุดของไซต์ stackexchange ทั้งหมดเนื่องจากมีคำถามที่ชัดเจนซึ่งสามารถมีสุขภาพดีได้ตลอดเวลา สิ่งที่ชัดเจนสำหรับคุณอาจไม่ชัดเจนสำหรับคนอื่นและในทางกลับกัน :) การแบ่งปันกำลังห่วงใย
Andreas Johansson

2
@ จัสตินเลขที่ หัวข้อนั้นดูเหมือนว่าฉันจะคาดการณ์สถานการณ์ที่มีตัวเลือกบังคับระหว่างรหัสที่มีประสิทธิภาพหรือรหัสที่สามารถบำรุงรักษาได้ ผู้ถามไม่ได้บอกว่าเขาพบตัวเองบ่อยครั้งเพียงใดในสถานการณ์นั้นและผู้ตอบคำถามดูเหมือนจะไม่ได้อ้างว่าอยู่ในสถานการณ์นั้นบ่อยครั้ง
Peter Taylor

2
-1 สำหรับคำถาม เมื่อฉันอ่านมันฉันคิดว่านี่เป็นคนฟางเพื่อขับไล่คำตอบที่แท้จริงเพียงคำเดียว: "เพราะพวกเขาไม่ได้ใช้หลาม"
Ingo

คำตอบ:


38

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

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


8
"เมื่อมีคนพยายามที่จะต่อต้านมุมมองดังกล่าวมันเป็นเรื่องง่ายที่จะตกอยู่ใน - หรืออย่างน้อยก็ดูเหมือน - สุดโต่งอื่น ๆ " ฉันมีปัญหาตลอดเวลากับผู้คนที่คิดว่าฉันถือมุมมองตรงกันข้ามเมื่อฉันแค่สร้างความสมดุล ข้อเสีย ไม่เพียง แต่ในการเขียนโปรแกรมในทุกสิ่ง
jhocking

1
ฉันเบื่อที่ทุกคนพูดคุยเกี่ยวกับเรื่องนี้ว่าฉันโกรธและรับความสุดขั้ว ..
โทมัส Bonini

มีคำตอบที่ดีหลายอย่าง แต่ฉันคิดว่าคุณพยายามอย่างดีที่สุดในการอธิบายรายละเอียดที่มาของความคิดนี้ ขอบคุณทุกคนที่เกี่ยวข้อง!
justin

คำตอบของฉัน ... นักพัฒนาส่วนใหญ่ไม่ดีในงานของพวกเขา
TheCatWhisperer

38

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

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

ทำให้ถูกต้องได้รับมันสวยงามได้อย่างรวดเร็ว เพื่อให้.


ฉันชอบกฎของหัวแม่มือ: 'ทำให้มันสวยงามได้อย่างรวดเร็ว เพื่อให้'. ฉันจะเริ่มใช้สิ่งนั้น
Martin York

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

@ KeithB - ​​คุณสร้างจุดดีฉันจะเพิ่มไปยังคำตอบของฉัน
Joris Timmermans

+1: "ทำให้ถูกต้องทำให้สวยงามขึ้นเร็วขึ้นตามลำดับนั้น" สรุปดีมากซึ่งฉันเห็นด้วย 90% บางครั้งฉันสามารถแก้ไขข้อบกพร่องบางอย่างเท่านั้น (ทำให้ถูกต้อง) เมื่อฉันทำให้สวยงาม (และเข้าใจได้มากขึ้น)
Giorgio

+1 สำหรับ "อย่าลบเนื้อหาก่อนกำหนด" คำแนะนำเพื่อหลีกเลี่ยงการปรับให้เหมาะสมก่อนวัยอันควรไม่ได้รับอนุญาตให้ใช้อัลกอริธึมแบบโบนเฮด หากคุณกำลังเขียน Java และคุณมีคอลเลกชันที่คุณจะโทรหาบ่อยให้containsใช้ a HashSet, ไม่ใช่ ArrayListประสิทธิภาพอาจไม่สำคัญ แต่ไม่มีเหตุผลที่จะไม่ ใช้ประโยชน์จากความสอดคล้องกันระหว่างการออกแบบที่ดีและประสิทธิภาพ - หากการประมวลผลคอลเลกชันบางอย่างพยายามทำทุกอย่างในการส่งครั้งเดียวซึ่งอาจเป็นทั้งการอ่านและเร็วขึ้น (อาจ)
Tom Anderson

16

หากฉันสามารถสันนิษฐานได้ว่า "ยืม" @ ดีแผนภาพของ greengit และทำการเพิ่มเล็กน้อย:

|
P
E
R
F
O  *               X <- a program as first written
R   * 
M    *
A      *
N        *
C          *  *   *  *  *
E
|
O -- R E A D A B I L I T Y --

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

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


โดยส่วนตัวแล้วฉันคิดว่ามีอีกปลายหนึ่งของเส้นโค้งที่มันขึ้นไปทางด้านขวาอีกครั้ง (ตราบใดที่คุณเลื่อนไปทางขวาพอ (ซึ่งอาจหมายถึงการคิดขั้นตอนวิธีของคุณอีกครั้ง)
Martin York

2
+1 สำหรับ "โปรแกรมส่วนใหญ่มีพื้นที่เหลือเฟือสำหรับการปรับปรุงในทุกมิติ"
สตีเวน

5

แม่นยำเนื่องจากส่วนประกอบซอฟต์แวร์ที่มีประสิทธิภาพสูงโดยทั่วไปแล้วจะมีขนาดที่ซับซ้อนกว่าส่วนประกอบซอฟต์แวร์อื่น ๆ (สิ่งอื่น ๆ ทั้งหมดเท่ากัน)

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

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

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

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


3

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


2
    |
    P
    E
    R
    F
    O *
    R * 
    M *
    A *
    ไม่มี *
    C * * * * *
    E
    |
    O - ความพร้อมใช้งาน -

อย่างที่เห็น...

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

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


1

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


1

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

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

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

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


1

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

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


1

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

มันเป็นสิ่งภายนอกเชิงลบเชิงเศรษฐกิจคล้ายกับรูปแบบของมลพิษที่ถูกละเลย ดังนั้นอัตราส่วนค่าใช้จ่าย / ผลประโยชน์ของการคิดเกี่ยวกับการทำงานเลยเบ้จากความเป็นจริงทางจิตใจ

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

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


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

1

ฉันคิดว่ามันยากที่จะทำให้สำเร็จทั้งสาม สองฉันคิดว่าเป็นไปได้ ตัวอย่างเช่นฉันคิดว่าเป็นไปได้ที่จะบรรลุประสิทธิภาพและความสามารถในการอ่านได้ในบางกรณี แต่การบำรุงรักษาอาจทำได้ยากด้วยโค้ดไมโครจูน โดยทั่วไปโค้ดที่มีประสิทธิภาพที่สุดในโลกจะขาดทั้งความสามารถในการบำรุงรักษาและความสามารถในการอ่านซึ่งอาจเป็นที่ชัดเจนสำหรับคนส่วนใหญ่ยกเว้นว่าคุณเป็นคนที่สามารถเข้าใจมือของ SOA-vectorized, SIMD แบบหลายเธรดที่ Intel เขียน อัลกอริธึมที่ใช้ในอุตสาหกรรมที่มีเอกสารทางคณิตศาสตร์ 40 หน้าเผยแพร่เมื่อ 2 เดือนที่ผ่านมาและห้องสมุด 12 แห่งที่มีรหัสสำหรับโครงสร้างข้อมูลที่ซับซ้อนอย่างเหลือเชื่อ

Micro-ประสิทธิภาพ

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

ดังนั้นแนวคิดนี้ว่าการปรับอัลกอริทึมให้ดีที่สุดเสมอคือการเพิ่มประสิทธิภาพที่เกี่ยวข้องกับรูปแบบการเข้าถึงหน่วยความจำจึงเป็นสิ่งที่ฉันไม่เห็นด้วย แน่นอนถ้าคุณใช้การเรียงลำดับแบบไม่มีฟองการเพิ่มประสิทธิภาพขนาดเล็กไม่สามารถช่วยคุณได้ ... แต่ด้วยเหตุผลฉันไม่คิดว่ามันจะชัดเจน และการเพิ่มประสิทธิภาพอัลกอริธึมที่สามารถรักษาได้ยากกว่าการปรับให้เหมาะสมแบบไมโคร ฉันจะพบว่ามันง่ายกว่ามากในการดูแลรักษาพูดว่า Embree ของ Intel ซึ่งใช้อัลกอริทึม BVH แบบคลาสสิกและตรงไปตรงมาและเพียงแค่ micro-tunes อึออกมาจากรหัส OpenVDB ของ Dreamwork สำหรับวิธีการที่ทันสมัย ดังนั้นในอุตสาหกรรมของฉันอย่างน้อยฉันก็อยากเห็นคนที่คุ้นเคยกับสถาปัตยกรรมคอมพิวเตอร์เพิ่มประสิทธิภาพมากขึ้นเช่นเดียวกับที่ Intel มีเมื่อพวกเขาก้าวเข้ามาในฉาก เมื่อเทียบกับการสร้างอัลกอริธึมและโครงสร้างข้อมูลใหม่นับพัน ด้วยการเพิ่มประสิทธิภาพขนาดเล็กที่มีประสิทธิภาพผู้คนอาจพบเหตุผลน้อยลงและน้อยลงในการคิดค้นอัลกอริทึมใหม่

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

ภาษาหน้าที่

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

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

ความสามารถในการอ่านกับการบำรุงรักษา

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

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


1
"Micro-Efficiency" เป็นคำที่เหมือนกับการพูดว่า "ไม่มีสิ่งใดในการเข้าถึงหน่วยความจำ O (1)"
Caleth

0

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

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


แน่นอนคุณสามารถอุทิศมากขึ้นเวลา แต่ในที่สุดคุณจะเริ่มคำถามว่าทำไมนักพัฒนาจะใช้เวลาปิดโปรแกรม emacs จะแสดงความรักสำหรับเด็กของพวกเขาและที่จุดที่คุณอยู่โดยทั่วไปเชลดอนจากทฤษฎีบิ๊กแบ
deworde

0

เพราะโปรแกรมเมอร์ผู้มีประสบการณ์ได้เรียนรู้ว่ามันเป็นเรื่องจริง

เราได้ทำงานกับโค้ดที่ไม่ติดขัดและไม่ได้มาตรฐานและไม่มีปัญหาด้านประสิทธิภาพ

เราได้ทำงานกับโค้ดจำนวนมากซึ่งการแก้ไขปัญหาประสิทธิภาพนั้นซับซ้อนมาก

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


0

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

นี่คือสิ่งที่ฉันคิดว่ามีชื่อเสียงที่สุด ที่นำมาจาก Quake III Arena และประกอบกับจอห์น Carmak แต่ฉันคิดว่ามีการซ้ำหลายฟังก์ชั่นนี้และมันก็ไม่ได้สร้างขึ้นมาโดยเขา ( ไม่ได้เป็นวิกิพีเดียที่ดี? )

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
    //      y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

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