ประสิทธิภาพของอัลกอริทึม
ในวิทยาการคอมพิวเตอร์ประสิทธิภาพของอัลกอริทึมเป็นคุณสมบัติของอัลกอริทึมที่เกี่ยวข้องกับปริมาณทรัพยากรการคำนวณที่อัลกอริทึมใช้ ประสิทธิภาพของอัลกอริทึมอาจเปรียบได้กับประสิทธิภาพการผลิต ทางวิศวกรรม สำหรับกระบวนการที่ทำซ้ำหรือต่อเนื่อง
เพื่อให้ได้ประสิทธิภาพสูงสุด ควรลดการใช้ทรัพยากรให้น้อยที่สุด อย่างไรก็ตาม ทรัพยากรที่แตกต่างกัน เช่นเวลาและ ความซับซ้อน ของพื้นที่ไม่สามารถเปรียบเทียบกันได้โดยตรง ดังนั้น การที่อัลกอริทึมใดในสองอัลกอริทึมจะมีประสิทธิภาพมากกว่ากันนั้น มักขึ้นอยู่กับว่ามาตรวัดประสิทธิภาพใดที่ถูกพิจารณาว่าสำคัญที่สุด
ตัวอย่างเช่นCycle SortและTimSortต่างก็เป็นอัลกอริธึมที่ใช้เรียงลำดับรายการจากน้อยไปมาก Cycle Sort จะจัดเรียงรายการโดยใช้เวลาแปรผันตามจำนวนองค์ประกอบยกกำลังสอง ((ดูสัญกรณ์ Big O ) แต่ลดการเขียนลงในอาร์เรย์เดิมให้น้อยที่สุด และต้องการ หน่วยความจำเพิ่มเติมเพียงเล็กน้อยซึ่งคงที่เมื่อเทียบกับความยาวของรายการ (). Timsort เรียงลำดับรายการตามเวลาแบบลิเนียร์ลิมิทึม (แปรผันตามปริมาณคูณด้วยลอการิทึมของปริมาณนั้น) ตามความยาวของรายการ () แต่มีความต้องการพื้นที่เชิงเส้นตามความยาวของรายการ (ถ้าหากจำเป็นต้องเรียงลำดับรายการขนาดใหญ่ด้วยความเร็วสูงสำหรับแอปพลิเคชันใดแอปพลิเคชันหนึ่ง timsort จะเป็นตัวเลือกที่ดีกว่า อย่างไรก็ตาม หากการลดรอบการเขียนโปรแกรม/ลบ และการใช้หน่วยความจำของการเรียงลำดับมีความสำคัญมากกว่า cycle sort จะเป็นตัวเลือกที่ดีกว่า
พื้นหลัง
เอดา โลฟเลซได้เน้นย้ำถึงความสำคัญของประสิทธิภาพในแง่ของเวลาในปี ค.ศ. 1843 โดยนำไปประยุกต์ใช้กับเครื่องวิเคราะห์เชิงกลของชาร์ลส์ แบ็บเบจ :
"ในการคำนวณเกือบทุกครั้ง มีความเป็นไปได้มากมายในการจัดเรียงลำดับของกระบวนการ และต้องพิจารณาปัจจัยต่างๆ หลายประการในการเลือกการจัดเรียงเหล่านั้นเพื่อวัตถุประสงค์ของเครื่องจักรคำนวณ วัตถุประสงค์ที่สำคัญประการหนึ่งคือการเลือกการจัดเรียงที่มีแนวโน้มที่จะลดเวลาที่จำเป็นในการคำนวณให้น้อยที่สุด" [ 1 ]
คอมพิวเตอร์อิเล็กทรอนิกส์ยุคแรกมีทั้งความเร็ว ที่จำกัด และหน่วยความจำแบบเข้าถึงโดยสุ่ม (RAM ) ที่จำกัด ดังนั้นจึงเกิดการแลกเปลี่ยนระหว่างพื้นที่และเวลาขึ้นงาน หนึ่ง อาจใช้อัลกอริทึมที่เร็วซึ่งใช้หน่วยความจำมาก หรืออาจใช้อัลกอริทึมที่ช้าซึ่งใช้หน่วยความจำน้อย การแลกเปลี่ยนทางวิศวกรรมจึงเป็นการใช้อัลกอริทึมที่เร็วที่สุดเท่าที่จะใส่ลงในหน่วยความจำที่มีอยู่ได้
คอมพิวเตอร์สมัยใหม่เร็วกว่าคอมพิวเตอร์รุ่นแรกๆ อย่างมาก และมีหน่วยความจำให้ใช้งานมากกว่าเดิม ( กิกะไบต์ แทนที่จะเป็นกิโลไบต์ ) อย่างไรก็ตามโดนัลด์ คนูธเน้นย้ำว่าประสิทธิภาพยังคงเป็นสิ่งสำคัญที่ต้องพิจารณา:
"ในสาขาวิศวกรรมที่ได้รับการยอมรับ การปรับปรุง 12% ซึ่งทำได้ง่ายนั้นไม่เคยถูกมองว่าเป็นเรื่องเล็กน้อย และฉันเชื่อว่ามุมมองเดียวกันนี้ควรนำมาใช้ในวิศวกรรมซอฟต์แวร์" [ 2 ]
ในยุคของAIแม้ว่า LLM จะสามารถสร้างโค้ดที่ใช้งานได้ แต่โค้ดเหล่านี้มักจะไม่ตรงตาม มาตรฐาน ประสิทธิภาพที่จำเป็นในแอปพลิเคชันที่มีทรัพยากรจำกัดหรือคำนึงถึงเวลา[ 3 ]ทำให้ประสิทธิภาพของโค้ดกลายเป็นปัญหาคอขวดที่สำคัญสำหรับการใช้งานจริง
ภาพรวม
อัลกอริทึมจะถือว่ามีประสิทธิภาพหากการใช้ทรัพยากร หรือที่เรียกว่าต้นทุนการคำนวณ อยู่ในระดับที่ยอมรับได้หรือต่ำกว่านั้น โดยทั่วไปแล้ว 'ยอมรับได้' หมายความว่า อัลกอริทึมจะทำงานได้ในเวลาหรือพื้นที่ที่เหมาะสมบนคอมพิวเตอร์ที่มีอยู่ โดยปกติแล้วจะขึ้นอยู่กับขนาดของข้อมูลป้อนเข้า นับตั้งแต่ทศวรรษ 1950 คอมพิวเตอร์มีการเพิ่มขึ้นอย่างมากทั้งในด้านกำลังการคำนวณและปริมาณหน่วยความจำ ดังนั้นระดับที่ยอมรับได้ในปัจจุบันจึงอาจไม่เป็นที่ยอมรับเมื่อ 10 ปีที่แล้วด้วยซ้ำ ในความเป็นจริง ด้วยกำลังการประมวลผลของคอมพิวเตอร์ที่เพิ่มขึ้นเป็นสองเท่าโดยประมาณทุกๆ 2 ปีงานที่ทำได้อย่างมีประสิทธิภาพในระดับที่ยอมรับได้บนสมาร์ทโฟนและระบบฝังตัว ในปัจจุบัน อาจไม่มีประสิทธิภาพในระดับที่ยอมรับไม่ได้สำหรับเซิร์ฟเวอร์ อุตสาหกรรม เมื่อ 10 ปีที่แล้ว
ผู้ผลิตคอมพิวเตอร์มักออกรุ่นใหม่ๆ อยู่เสมอ ซึ่งมักมีประสิทธิภาพ สูงขึ้น ค่าใช้จ่ายด้านซอฟต์แวร์อาจค่อนข้างสูง ดังนั้นในบางกรณี วิธีที่ง่ายและประหยัดที่สุดในการเพิ่มประสิทธิภาพอาจเป็นการซื้อคอมพิวเตอร์ที่เร็วขึ้นโดยตรง โดยมีเงื่อนไขว่าต้องสามารถใช้งานร่วมกับคอมพิวเตอร์เครื่องเดิมได้
มีหลายวิธีในการวัดทรัพยากรที่ใช้โดยอัลกอริทึม: สองวิธีที่พบมากที่สุดคือความเร็วและการใช้หน่วยความจำ วิธีอื่นๆ อาจรวมถึงความเร็วในการส่งข้อมูล การใช้ดิสก์ชั่วคราว การใช้ดิสก์ระยะยาว การใช้พลังงาน ต้นทุนรวมในการเป็นเจ้าของเวลาตอบสนองต่อสิ่งเร้าภายนอก เป็นต้น การวัดเหล่านี้หลายอย่างขึ้นอยู่กับขนาดของข้อมูลป้อนเข้าอัลกอริทึม กล่าวคือปริมาณข้อมูลที่จะต้องประมวลผล นอกจากนี้ยังอาจขึ้นอยู่กับวิธีการจัดเรียงข้อมูลด้วย ตัวอย่างเช่นอัลกอริทึมการเรียงลำดับ บางตัว ทำงานได้ไม่ดีกับข้อมูลที่เรียงลำดับแล้ว หรือข้อมูลที่เรียงลำดับย้อนกลับ
ในทางปฏิบัติ มีปัจจัยอื่นๆ ที่อาจส่งผลต่อประสิทธิภาพของอัลกอริทึม เช่น ข้อกำหนดด้านความแม่นยำและ/หรือความน่าเชื่อถือ ดังที่ได้อธิบายไว้ด้านล่าง วิธีการนำอัลกอริทึมไปใช้งานก็มีผลอย่างมากต่อประสิทธิภาพที่แท้จริงเช่นกัน แม้ว่าหลายแง่มุมในเรื่องนี้เกี่ยวข้องกับประเด็นการปรับให้เหมาะสม ที่สุดก็ตาม
การวิเคราะห์เชิงทฤษฎี
ในการวิเคราะห์เชิงทฤษฎีของอัลกอริทึมวิธีปฏิบัติทั่วไปคือการประมาณความซับซ้อนในเชิงอะซิมโทติก สัญลักษณ์ที่ใช้กันมากที่สุดในการอธิบายการใช้ทรัพยากรหรือ "ความซับซ้อน" คือสัญลักษณ์ Big OของDonald Knuthซึ่งแสดงถึงความซับซ้อนของอัลกอริทึมเป็นฟังก์ชันของขนาดของข้อมูลป้อนเข้าสัญกรณ์ Big O เป็นการ วัดความ ซับซ้อนของฟังก์ชันเชิงอะซิมโทติก โดยที่หมายความว่าโดยประมาณแล้ว ระยะเวลาที่ใช้ในการประมวลผลอัลกอริทึมจะแปรผันตรงกับโดยละเว้นพจน์ลำดับต่ำกว่าที่มีส่วนร่วมน้อยกว่าเพื่อการเติบโตของฟังก์ชันดังกล่าวมีขนาดใหญ่ขึ้นอย่างไม่มีกำหนดการประมาณค่านี้อาจทำให้เข้าใจผิดได้เมื่อมีขนาดเล็ก แต่โดยทั่วไปแล้วมีความแม่นยำเพียงพอเมื่อมีขนาดใหญ่เนื่องจากสัญลักษณ์เป็นแบบเชิงเส้นกำกับ ตัวอย่างเช่น การเรียงลำดับแบบบับเบิลอาจเร็วกว่าการเรียงลำดับแบบผสานเมื่อมีรายการที่ต้องเรียงลำดับเพียงไม่กี่รายการ อย่างไรก็ตาม การใช้งานทั้งสองแบบน่าจะตรงตามข้อกำหนดด้านประสิทธิภาพสำหรับรายการขนาดเล็ก โดยทั่วไปแล้ว โปรแกรมเมอร์สนใจอัลกอริทึมที่สามารถปรับขนาดได้อย่างมีประสิทธิภาพสำหรับขนาดอินพุตขนาดใหญ่ และการเรียงลำดับแบบผสานเป็นที่นิยมมากกว่าการเรียงลำดับแบบบับเบิลสำหรับรายการที่มีความยาวที่พบในโปรแกรมที่เน้นข้อมูลจำนวนมาก
ตัวอย่างบางส่วนของการใช้สัญกรณ์ Big O กับความซับซ้อนของเวลาเชิงอะซิมโทติกของอัลกอริทึม ได้แก่:
| สัญกรณ์ | ชื่อ | ตัวอย่าง |
|---|---|---|
| คงที่ | การหาค่ามัธยฐานจากรายการค่าที่เรียงลำดับแล้ว การใช้ตารางค้นหาที่ มีขนาดคงที่ การใช้ ฟังก์ชันแฮชที่เหมาะสมสำหรับการค้นหารายการ | |
| ลอการิทึม | การค้นหารายการในอาร์เรย์ที่เรียงลำดับแล้วโดยใช้การค้นหาแบบไบนารี หรือ ต้นไม้ค้นหาแบบสมดุลตลอดจนการดำเนินการทั้งหมดในฮีปแบบไบโนเมียล | |
| เชิงเส้น | การค้นหารายการในรายการที่ไม่เรียงลำดับหรือโครงสร้างต้นไม้ที่ผิดรูป (กรณีที่เลวร้ายที่สุด) หรือในอาร์เรย์ที่ไม่เรียงลำดับ การบวก จำนวนเต็ม nบิตสองจำนวนโดยใช้การทดแบบระลอกคลื่น | |
| แบบเชิงเส้น แบบลอการิทึมเชิงเส้น หรือแบบกึ่งเชิงเส้น | การแปลงฟูริเยร์แบบเร็ว (Fast Fourier Transform ); การ เรียงลำดับแบบฮีปซอร์ ต (heapsort) , การเรียงลำดับแบบ ควิกซอร์ต (quicksort ) ( กรณีที่ดีที่สุดและกรณีเฉลี่ย ) หรือการเรียงลำดับแบบผสาน (merge sort) | |
| กำลังสอง | การคูณ เลข สอง จำนวนที่มี nหลักด้วยอัลกอริทึมแบบง่ายๆเช่นบับเบิลซอร์ต (กรณีที่เลวร้ายที่สุดหรือการใช้งานแบบง่ายๆ), เชลล์ซอร์ต , ควิกซอร์ต ( กรณีที่เลวร้ายที่สุด ), ซีเล็คชั่นซอร์ตหรืออินเสิร์ชชั่นซอร์ต | |
| เลขชี้กำลัง | การหาคำตอบที่เหมาะสมที่สุด (ไม่ใช่คำตอบโดยประมาณ ) สำหรับปัญหาพนักงานขายเดินทางโดยใช้การเขียนโปรแกรมเชิงพลวัต การ ตรวจสอบ ว่าข้อความตรรกะสองข้อความนั้นเทียบเท่ากันหรือไม่โดยใช้การค้นหาแบบบรูทฟอร์ซ |
การวัดผลการปฏิบัติงาน
สำหรับการพัฒนาซอฟต์แวร์เวอร์ชันใหม่ หรือเพื่อเปรียบเทียบกับระบบคู่แข่ง บางครั้งจึงมีการใช้ เกณฑ์มาตรฐาน (benchmark)ซึ่งช่วยในการวัดประสิทธิภาพเชิงเปรียบเทียบของอัลกอริทึม ตัวอย่างเช่น หาก มีการสร้าง อัลกอริทึมการเรียงลำดับ ใหม่ ก็สามารถนำไปเปรียบเทียบกับรุ่นก่อนหน้าเพื่อให้แน่ใจว่าอย่างน้อยก็มีประสิทธิภาพเท่าเดิมกับข้อมูลที่ทราบ โดยคำนึงถึงการปรับปรุงฟังก์ชันการทำงานใดๆ ด้วย เกณฑ์มาตรฐานสามารถใช้โดยลูกค้าเมื่อเปรียบเทียบผลิตภัณฑ์ต่างๆ จากผู้จำหน่ายหลายราย เพื่อประเมินว่าผลิตภัณฑ์ใดเหมาะสมกับความต้องการเฉพาะของตนมากที่สุดในแง่ของฟังก์ชันการทำงานและประสิทธิภาพ ตัวอย่างเช่น ใน โลก ของเมนเฟรม ผลิตภัณฑ์ การเรียงลำดับที่เป็นกรรมสิทธิ์บางอย่างจากบริษัทซอฟต์แวร์อิสระ เช่นSyncsortแข่งขันกับผลิตภัณฑ์จากผู้จำหน่ายรายใหญ่ เช่นIBMในด้านความเร็ว
เกณฑ์มาตรฐานบางอย่างเปิดโอกาสให้สร้างการวิเคราะห์เปรียบเทียบความเร็วสัมพัทธ์ของภาษาคอมไพล์และภาษาตีความต่างๆ เช่น[ 4 ] [ 5 ] และเกมเกณฑ์มาตรฐานภาษาคอมพิวเตอร์เปรียบเทียบประสิทธิภาพของการใช้งานปัญหาการเขียนโปรแกรมทั่วไปในภาษาการเขียนโปรแกรมหลายภาษา
แม้แต่การสร้างเกณฑ์มาตรฐานแบบ " ทำเอง " ก็สามารถแสดงให้เห็นถึงประสิทธิภาพเชิงเปรียบเทียบของภาษาการเขียนโปรแกรมต่างๆ โดยใช้เกณฑ์ต่างๆ ที่ผู้ใช้กำหนด ซึ่งค่อนข้างง่าย ดังที่ "การรวบรวมประสิทธิภาพของภาษาทั้งเก้า" โดย Christopher W. Cowell-Shah แสดงให้เห็นเป็นตัวอย่าง[ 6 ]
ข้อกังวลเกี่ยวกับการดำเนินการ
ปัญหาในการนำไปใช้งานอาจส่งผลต่อประสิทธิภาพได้เช่นกัน เช่น การเลือกภาษาโปรแกรม หรือวิธีการเขียนโค้ดอัลกอริธึมจริง ๆ[ 7 ]หรือการเลือกคอมไพเลอร์สำหรับภาษาใดภาษาหนึ่ง หรือตัวเลือกการคอมไพล์ที่ใช้ หรือแม้แต่ระบบปฏิบัติการที่ใช้ ในหลายกรณี ภาษาที่ใช้ตัวแปลภาษาอาจช้ากว่าภาษาที่ใช้คอมไพเลอร์มาก[ 4 ]ดูบทความเกี่ยวกับการคอมไพล์แบบทันเวลาและภาษาที่ใช้ตัวแปลภาษา
มีปัจจัยอื่นๆ ที่อาจส่งผลต่อปัญหาด้านเวลาหรือพื้นที่ แต่ปัจจัยเหล่านี้อาจอยู่นอกเหนือการควบคุมของโปรแกรมเมอร์ ซึ่งรวมถึงการจัดเรียงข้อมูลความละเอียดของข้อมูลตำแหน่งแคช ความสอดคล้องของแคชการเก็บขยะ การประมวลผลแบบขนานระดับคำสั่ง การทำงานแบบมัลติเธรด (ทั้งในระดับฮาร์ดแวร์หรือซอฟต์แวร์) การทำงาน แบบมัลติทาสกิ้งพร้อมกันและการเรียกใช้ซับรูทีน[ 8 ]
โปรเซสเซอร์บางตัวมีความสามารถในการประมวลผลแบบเวกเตอร์ซึ่งช่วยให้คำสั่งเดียวสามารถทำงานกับตัวถูกดำเนินการหลายตัวได้อย่างไรก็ตาม การใช้งานความสามารถเหล่านี้อาจง่ายหรือยากสำหรับโปรแกรมเมอร์หรือคอมไพเลอร์ อัลกอริทึมที่ออกแบบมาสำหรับการประมวลผลแบบลำดับอาจต้องได้รับการออกแบบใหม่ทั้งหมดเพื่อให้สามารถใช้ประโยชน์จากการประมวลผลแบบขนานหรืออาจสามารถกำหนดค่าใหม่ได้อย่างง่ายดาย เนื่องจาก การประมวลผล แบบขนานและแบบกระจาย มีความสำคัญมากขึ้นในช่วงปลายทศวรรษ 2010 จึงมีการลงทุนมากขึ้นในAPI ระดับสูง ที่มีประสิทธิภาพ สำหรับระบบการประมวลผลแบบขนานและแบบกระจาย เช่นCUDA , TensorFlow , Hadoop , OpenMPและMPI
อีกปัญหาหนึ่งที่อาจเกิดขึ้นในการเขียนโปรแกรมคือ โปรเซสเซอร์ที่เข้ากันได้กับ ชุดคำสั่งเดียวกัน(เช่นx86-64หรือARM ) อาจใช้งานคำสั่งในลักษณะที่แตกต่างกัน ทำให้คำสั่งที่ทำงานได้เร็วในบางรุ่นอาจทำงานได้ช้าในรุ่นอื่น ซึ่งมักเป็นความท้าทายสำหรับคอมไพเลอร์ที่เน้นการปรับแต่งประสิทธิภาพ เนื่องจากคอมไพเลอร์ ต้องมีความรู้เกี่ยวกับCPUและฮาร์ดแวร์อื่นๆ ที่มีอยู่ในแพลตฟอร์มเป้าหมายอย่างละเอียด เพื่อปรับแต่งโปรแกรมให้มีประสิทธิภาพสูงสุด ในกรณีที่รุนแรง คอมไพเลอร์อาจถูกบังคับให้จำลองคำสั่งที่ไม่รองรับบนแพลตฟอร์มเป้าหมาย ทำให้ต้องสร้างโค้ดหรือเชื่อมโยงการเรียกใช้ไลบรารีภายนอกเพื่อให้ได้ผลลัพธ์ที่ไม่สามารถคำนวณได้บนแพลตฟอร์มนั้น แม้ว่าคำสั่งนั้นจะได้รับการสนับสนุนโดยธรรมชาติและมีประสิทธิภาพมากกว่าในฮาร์ดแวร์บนแพลตฟอร์มอื่นๆ ก็ตาม กรณีนี้มักเกิดขึ้นในระบบฝังตัว โดยเฉพาะอย่างยิ่ง ในส่วนของการคำนวณเลขทศนิยม เนื่องจาก ไมโครคอนโทรลเลอร์ขนาดเล็กและใช้พลังงานต่ำ มักขาดการสนับสนุนฮาร์ดแวร์สำหรับการคำนวณเลขทศนิยม จึงต้องใช้รูทีนซอฟต์แวร์ที่มีค่าใช้จ่ายในการคำนวณสูงเพื่อให้ได้ผลลัพธ์การคำนวณเลขทศนิยม
การวัดการใช้ทรัพยากร
โดยปกติแล้ว ค่าที่วัดได้จะแสดงออกมาในรูปของฟังก์ชันของขนาดของข้อมูลป้อนเข้า.
มาตรการที่ใช้กันทั่วไปสองอย่างคือ:
- เวลา : อัลกอริทึมนี้ใช้เวลานานเท่าใดจึงจะเสร็จสมบูรณ์?
- พื้นที่ : อัลกอริทึมต้องการหน่วยความจำในการทำงาน (โดยทั่วไปคือ RAM) เท่าใด? ซึ่งประกอบด้วยสองส่วน คือ ปริมาณหน่วยความจำที่โค้ดต้องการ (การใช้พื้นที่เสริม) และปริมาณหน่วยความจำที่จำเป็นสำหรับข้อมูลที่โค้ดประมวลผล (การใช้พื้นที่ภายใน)
สำหรับคอมพิวเตอร์ที่ใช้พลังงานจากแบตเตอรี่ (เช่นแล็ปท็อปและสมาร์ทโฟน ) หรือสำหรับการคำนวณที่ยาวนาน/ขนาดใหญ่มาก (เช่นซูเปอร์คอมพิวเตอร์ ) มาตรวัดอื่นๆ ที่น่าสนใจ ได้แก่:
- การใช้พลังงานโดยตรง : พลังงานที่จำเป็นโดยตรงในการใช้งานคอมพิวเตอร์
- การใช้พลังงานทางอ้อม : พลังงานที่จำเป็นสำหรับการทำความเย็น การให้แสงสว่าง เป็นต้น
ข้อมูล ณ ปี 2018การใช้พลังงานกำลังกลายเป็นตัวชี้วัดที่สำคัญมากขึ้นสำหรับงานคำนวณทุกประเภทและทุกขนาด ตั้งแต่อุปกรณ์Internet of Things (IoT) แบบฝังตัว ไปจนถึง อุปกรณ์System-on-Chip และ ศูนย์ ข้อมูลขนาดใหญ่ แนวโน้มนี้มักถูกเรียกว่า การคำนวณที่เป็นมิตร ต่อสิ่งแวดล้อม (Green Computing )
มาตรวัดประสิทธิภาพการคำนวณที่ไม่ค่อยพบเห็นทั่วไป อาจมีความเกี่ยวข้องในบางกรณีเช่นกัน:
- ขนาดการส่งข้อมูล : แบนด์วิดท์อาจเป็นปัจจัยจำกัดการบีบอัดข้อมูลสามารถใช้เพื่อลดปริมาณข้อมูลที่จะส่ง การแสดงภาพหรือรูปภาพ (เช่นโลโก้ Google ) อาจส่งผลให้มีการส่งข้อมูลหลายหมื่นไบต์ (48K ในกรณีนี้) เมื่อเทียบกับการส่งข้อมูลเพียงหกไบต์สำหรับข้อความ "Google" ซึ่งมีความสำคัญสำหรับ งาน ประมวลผลที่เน้นการรับส่งข้อมูล (I/O bound computing tasks)
- พื้นที่ภายนอก : พื้นที่ที่จำเป็นบนดิสก์หรืออุปกรณ์หน่วยความจำภายนอกอื่นๆ ซึ่งอาจใช้สำหรับการจัดเก็บชั่วคราวในขณะที่กำลังดำเนินการตามอัลกอริทึม หรืออาจเป็นการจัดเก็บระยะยาวที่จำเป็นสำหรับการอ้างอิงในอนาคต
- เวลาตอบสนอง ( ความหน่วง ): สิ่งนี้มีความสำคัญอย่างยิ่งในแอปพลิเคชันแบบเรียลไทม์เมื่อระบบคอมพิวเตอร์ต้องตอบสนองต่อเหตุการณ์ภายนอกอย่างรวดเร็ว
- ต้นทุนรวมในการเป็นเจ้าของ : โดยเฉพาะอย่างยิ่งหากคอมพิวเตอร์เครื่องนั้นถูกใช้เฉพาะกับอัลกอริทึมใดอัลกอริทึมหนึ่งโดยเฉพาะ
เวลา
ทฤษฎี
การวิเคราะห์อัลกอริทึมโดยทั่วไปใช้แนวคิดเช่นความซับซ้อนของเวลาสามารถใช้เพื่อประมาณเวลาในการทำงานเป็นฟังก์ชันของขนาดของข้อมูลอินพุต ผลลัพธ์มักจะแสดงโดยใช้สัญกรณ์ Big Oซึ่งมีประโยชน์สำหรับการเปรียบเทียบอัลกอริทึม โดยเฉพาะอย่างยิ่งเมื่อต้องประมวลผลข้อมูลจำนวนมาก จำเป็นต้องมีการประมาณค่าที่ละเอียดกว่าเพื่อเปรียบเทียบประสิทธิภาพของอัลกอริทึมเมื่อปริมาณข้อมูลมีน้อย แม้ว่าสิ่งนี้อาจมีความสำคัญน้อยกว่าก็ตามอัลกอริทึมแบบขนานอาจวิเคราะห์ได้ยากกว่า
ฝึกฝน
สามารถใช้เกณฑ์มาตรฐานในการประเมินประสิทธิภาพของอัลกอริทึมในการใช้งานจริงได้ ภาษาโปรแกรมหลายภาษามีฟังก์ชันที่แสดงเวลาการ ใช้งาน CPUสำหรับอัลกอริทึมที่ใช้เวลานาน เวลาที่ใช้ไปก็อาจเป็นสิ่งที่น่าสนใจเช่นกัน โดยทั่วไปแล้วควรหาค่าเฉลี่ยของผลลัพธ์จากการทดสอบหลายครั้ง
การวิเคราะห์ประสิทธิภาพการทำงานตามรอบการทำงานอาจมีความอ่อนไหวต่อการกำหนดค่าฮาร์ดแวร์และความเป็นไปได้ที่โปรแกรมหรือภารกิจอื่นๆ จะทำงานพร้อมกันในสภาพแวดล้อมแบบมัลติโปรเซสซิ่งและมัลติโปรแกรมมิ่ง
การทดสอบประเภทนี้ขึ้นอยู่กับการเลือกภาษาโปรแกรม คอมไพเลอร์ และตัวเลือกของคอมไพเลอร์เป็นอย่างมาก ดังนั้นอัลกอริทึมที่นำมาเปรียบเทียบกันจะต้องถูกนำไปใช้งานภายใต้เงื่อนไขเดียวกันทั้งหมด
ช่องว่าง
ส่วนนี้เกี่ยวข้องกับการใช้ทรัพยากรหน่วยความจำ ( รี จิสเตอร์แคช RAM หน่วยความจำเสมือน หน่วย ความจำรอง ) ในขณะที่อัลกอริทึมกำลังทำงาน เช่นเดียวกับการวิเคราะห์เวลาข้างต้น ให้วิเคราะห์อัลกอริทึม โดยทั่วไปจะใช้ การวิเคราะห์ ความซับซ้อนของพื้นที่เพื่อประมาณค่าหน่วยความจำที่จำเป็นในขณะรันไทม์ โดยเป็นฟังก์ชันของขนาดข้อมูลอินพุต ผลลัพธ์มักจะแสดงโดยใช้ สัญกร ณ์Big O
มีปัจจัยที่ต้องพิจารณาเกี่ยวกับการใช้งานหน่วยความจำมากถึงสี่ประการ:
- ปริมาณหน่วยความจำที่จำเป็นสำหรับการจัดเก็บโค้ดของอัลกอริทึม
- ปริมาณหน่วยความจำที่จำเป็นสำหรับข้อมูลขาเข้า
- ปริมาณหน่วยความจำที่จำเป็นสำหรับข้อมูลเอาต์พุต แต่ละ รายการ
- อัลกอริทึมบางอย่าง เช่น การเรียงลำดับ มักจะจัดเรียงข้อมูลขาเข้าใหม่และไม่ต้องการพื้นที่เพิ่มเติมสำหรับข้อมูลขาออก คุณสมบัตินี้เรียกว่า การทำงานแบบ " in-place "
- ปริมาณหน่วยความจำที่จำเป็นสำหรับใช้เป็นพื้นที่ทำงานระหว่างการคำนวณ
- ซึ่งรวมถึงตัวแปรโลคอลและพื้นที่สแต็กที่จำเป็นสำหรับรูทีนที่ถูกเรียกใช้ระหว่างการคำนวณ พื้นที่สแต็กนี้อาจมีปริมาณมากสำหรับอัลกอริธึมที่ใช้เทคนิคแบบเรียกซ้ำ
คอมพิวเตอร์อิเล็กทรอนิกส์รุ่นแรกๆ และคอมพิวเตอร์ส่วนบุคคลรุ่นแรกๆ มีหน่วยความจำใช้งาน (Working Memory) ในปริมาณค่อนข้างน้อย ตัวอย่างเช่นเครื่องคิดเลขแบบหน่วงเวลาอิเล็กทรอนิกส์ (EDSAC) ในปี 1949 มีหน่วยความจำใช้งานสูงสุด 1024 คำ (17 บิต) ในขณะที่ Sinclair ZX80 ในปี 1980 มาพร้อมกับหน่วยความจำใช้งาน 1024 ไบต์ (8 บิต) ในช่วงปลายปี 2010 คอมพิวเตอร์ส่วนบุคคล โดยทั่วไป จะมี RAM ระหว่าง 4 ถึง 32 GBซึ่งเพิ่มขึ้นมากกว่า 300 ล้านเท่า
การแคชและลำดับชั้นของหน่วยความจำ
คอมพิวเตอร์สมัยใหม่มีหน่วยความจำค่อนข้างมาก (อาจเป็นกิกะไบต์) ดังนั้นการบีบอัลกอริทึมให้พอดีกับหน่วยความจำที่มีจำกัดจึงไม่ใช่ปัญหาใหญ่เหมือนในอดีต อย่างไรก็ตาม ประเภทของหน่วยความจำและความเร็วในการเข้าถึงที่แตกต่างกันอาจมีความสำคัญ:
- รีจิสเตอร์ของโปรเซสเซอร์เป็นหน่วยความจำที่เร็วที่สุดแต่ใช้พื้นที่น้อยที่สุด การคำนวณโดยตรงส่วนใหญ่ในคอมพิวเตอร์สมัยใหม่เกิดขึ้นโดยใช้ตัวถูกดำเนินการต้นทางและปลายทางในรีจิสเตอร์ก่อนที่จะอัปเดตไปยังแคช หน่วยความจำหลัก และหน่วยความจำเสมือนหากจำเป็น โดยทั่วไปแล้ว บนแกนประมวลผลจะมีรีจิสเตอร์ให้ใช้งานได้ประมาณหลายร้อยไบต์หรือน้อยกว่านั้น แม้ว่าไฟล์รีจิสเตอร์อาจมีรีจิสเตอร์ทางกายภาพมากกว่า รีจิสเตอร์ ทางสถาปัตยกรรมที่กำหนดไว้ในสถาปัตยกรรมชุดคำสั่งก็ตาม
- หน่วยความจำแคชเป็นหน่วยความจำที่เร็วเป็นอันดับสองและเล็กเป็นอันดับสองในลำดับชั้นของหน่วยความจำ แคชมีอยู่ในโปรเซสเซอร์ เช่น CPU หรือ GPU ซึ่งโดยทั่วไปจะถูกใช้งานในRAM แบบคงที่แม้ว่าจะสามารถพบได้ในอุปกรณ์ต่อพ่วง เช่น ดิสก์ไดรฟ์ แคชของโปรเซสเซอร์มักมีลำดับชั้นหลายระดับ ของตัวเอง ระดับล่างจะมีขนาดใหญ่กว่า ช้ากว่า และโดยทั่วไปจะใช้ร่วมกันระหว่างคอร์ของโปรเซสเซอร์ในโปรเซสเซอร์แบบมัลติคอร์ในการประมวลผลตัวดำเนินการในหน่วยความจำแคชหน่วยประมวลผล จะต้องดึงข้อมูลจากแคช ทำการดำเนินการในรีจิสเตอร์ และเขียนข้อมูลกลับไปยังแคช กระบวนการนี้ทำงานด้วยความเร็วที่เทียบได้ (ช้ากว่าประมาณ 2-10 เท่า) กับ หน่วยคำนวณทางคณิตศาสตร์หรือหน่วยประมวลผลจุดลอยตัวของ CPU หรือ GPU หากอยู่ใน แคช ระดับL1 [ 9 ]จะช้าลงประมาณ 10 เท่าหากมีแคช L1 พลาดและต้องดึงข้อมูลจากแคช L2 และเขียนไปยังแคช L2และจะช้าลงอีก 10 เท่าหากมีแคช L2 พลาดและต้องดึงข้อมูลจากแคช L3หากมีอยู่
- หน่วยความจำหลักทางกายภาพส่วนใหญ่มักถูกนำไปใช้ในรูปแบบ RAM แบบไดนามิก (DRAM) หน่วยความจำหลักมีขนาดใหญ่กว่ามาก (โดยทั่วไปคือกิกะไบต์เมื่อเทียบกับ ≈8 เมกะไบต์ ) เมื่อเทียบกับแคช L3 ของ CPU โดยมีเวลาในการอ่านและเขียนที่ช้ากว่าโดยทั่วไป 10-100 เท่า[ 9 ]ณ ปี 2018ปัจจุบัน RAM ถูกนำมาติดตั้งบนชิป ประมวลผลมากขึ้นเรื่อย ๆในรูปแบบของหน่วยความจำ CPU หรือ GPU
- หน่วยความจำแบบเพจซึ่งมักใช้สำหรับ การจัดการ หน่วยความจำเสมือนคือหน่วยความจำที่จัดเก็บในหน่วยเก็บข้อมูลรองเช่นฮาร์ดดิสก์และเป็นส่วนขยายของลำดับชั้นหน่วยความจำที่ช่วยให้สามารถใช้พื้นที่จัดเก็บข้อมูลที่อาจมีขนาดใหญ่ขึ้นได้ โดยแลกกับความหน่วงที่สูงขึ้นมาก โดยทั่วไปจะช้ากว่าแคชมิสสำหรับค่าใน RAM ประมาณ 1,000 เท่า [ 9 ]แม้ว่าเดิมทีจะมีแรงจูงใจเพื่อสร้างความประทับใจว่ามีหน่วยความจำมากกว่าที่มีอยู่จริง แต่หน่วยความจำเสมือนมีความสำคัญมากกว่าในการใช้งานในปัจจุบันเนื่องจากการแลกเปลี่ยนระหว่างเวลาและพื้นที่และช่วยให้สามารถใช้งานเครื่องเสมือนได้[ 9 ]แคชมิสจากหน่วยความจำหลักเรียกว่าเพจฟอลต์และทำให้โปรแกรมทำงานช้าลงอย่างมาก
อัลกอริทึมที่มีความต้องการหน่วยความจำที่เหมาะสมกับหน่วยความจำแคช จะทำงานได้เร็วกว่าอัลกอริทึมที่เหมาะสมกับหน่วยความจำหลัก ซึ่งจะเร็วกว่าอัลกอริทึมที่ต้องใช้การแบ่งหน้าหน่วยความจำมาก ด้วยเหตุนี้นโยบายการแทนที่แคชจึงมีความสำคัญอย่างยิ่งต่อการประมวลผลประสิทธิภาพสูง เช่นเดียวกับการเขียนโปรแกรมที่คำนึงถึงแคชและการจัดเรียงข้อมูลยิ่งไปกว่านั้น บางระบบมีหน่วยความจำแคชมากถึงสามระดับ โดยมีความเร็วในการทำงานที่แตกต่างกัน ระบบต่างๆ จะมีปริมาณหน่วยความจำประเภทต่างๆ เหล่านี้แตกต่างกัน ดังนั้นผลกระทบของความต้องการหน่วยความจำของอัลกอริทึมจึงอาจแตกต่างกันอย่างมากในแต่ละระบบ
ในยุคแรกเริ่มของการคำนวณทางอิเล็กทรอนิกส์ หากอัลกอริทึมและข้อมูลของมันมีขนาดใหญ่เกินกว่าจะจัดเก็บในหน่วยความจำหลักได้ อัลกอริทึมนั้นก็จะไม่สามารถใช้งานได้ ในปัจจุบัน การใช้หน่วยความจำเสมือนดูเหมือนจะให้หน่วยความจำมากกว่าเดิมมาก แต่ก็แลกมาด้วยประสิทธิภาพที่ลดลง ความเร็วในการทำงานจะสูงขึ้นมากหากอัลกอริทึมและข้อมูลของมันเหมาะสมกับหน่วยความจำแคช ในกรณีนี้ การลดพื้นที่จัดเก็บจะช่วยลดเวลาในการทำงานลงด้วย นี่เรียกว่าหลักการของความใกล้เคียง (principle of locality ) ซึ่งสามารถแบ่งย่อยได้เป็น ความใกล้เคียงของ การอ้างอิง (locality of reference ) ความใกล้เคียงเชิงพื้นที่ ( spatial locality ) และความใกล้เคียงเชิงเวลา (temporal locality ) อัลกอริทึมที่ไม่สามารถจัดเก็บในหน่วยความจำแคชได้อย่างสมบูรณ์ แต่แสดงให้เห็นถึงความใกล้เคียงของการอ้างอิง อาจทำงานได้ค่อนข้างดี
ดูเพิ่มเติม
- การวิเคราะห์อัลกอริทึม — วิธีการกำหนดทรัพยากรที่จำเป็นสำหรับอัลกอริทึม
- เกณฑ์มาตรฐาน — วิธีการวัดเวลาและพื้นที่การประมวลผลเปรียบเทียบในกรณีที่กำหนด[ 10 ] [ 11 ] [ 12 ]
- กรณีที่ดีที่สุด แย่ที่สุด และเฉลี่ย — ข้อควรพิจารณาในการประมาณเวลาในการดำเนินการในสามสถานการณ์
- การปรับแต่งประสิทธิภาพของคอมไพเลอร์ — การปรับแต่งประสิทธิภาพที่ได้มาจากคอมไพเลอร์
- ทฤษฎีความซับซ้อนในการคำนวณ
- ประสิทธิภาพของคอมพิวเตอร์ — ตัวชี้วัดฮาร์ดแวร์คอมพิวเตอร์
- อัลกอริทึมเชิงประจักษ์ — การนำวิธีการเชิงประจักษ์มาใช้ในการศึกษาพฤติกรรมของอัลกอริทึม
- โครงร่างของอัลกอริธึม
- การเพิ่มประสิทธิภาพโปรแกรม
- การวิเคราะห์ประสิทธิภาพ — วิธีการวัดประสิทธิภาพที่แท้จริงของอัลกอริทึมในระหว่างการทำงาน