สิ่งที่คุณเรียกว่าเมื่อคุณเปลี่ยนเวลาดำเนินการ Big O ของฟังก์ชั่น [ปิด]


19

สมมติว่าฉันมีฟังก์ชั่นที่เรียงลำดับฐานข้อมูลในO(n^2)เวลา ฉันต้องการที่จะทำการปรับโครงสร้างใหม่เพื่อให้มันทำงานได้O(n log(n))ทันเวลาและในการทำเช่นนั้นฉันจะเปลี่ยนวิธีพื้นฐานในการทำงานของการดำเนินการในขณะที่รักษาค่าส่งคืนและอินพุตให้เท่ากัน

ฉันจะเรียกกิจกรรมการปรับโครงสร้างซ้ำนี้ว่าอะไร

"Speeding-up-ifying" ดูเหมือนไม่ถูกต้องเนื่องจากคุณสามารถทำให้อัลกอริทึมเร็วขึ้นโดยไม่ต้องเปลี่ยนความเร็ว O ขนาดใหญ่ที่มันทำงาน

"การทำให้เรียบง่าย" ก็ดูไม่ถูกต้องเช่นกัน

ฉันจะเรียกกิจกรรมนี้ว่าอะไร

ปรับปรุง

คำตอบที่ดีที่สุดที่ฉันสามารถหาได้คือการลดความซับซ้อนของเวลาแบบอสมมาตร


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

22
นี่ไม่ใช่การปรับโครงสร้างใหม่
theonlygusti

6
ฟังก์ชั่นการพูดอย่างเคร่งครัดซึ่งทำงานในO(log(n))เวลายังทำงานในO(n^2)เวลา ความหมายของO(n^2)"ไม่เติบโตเร็วกว่ากำลังสอง" คุณอาจหมายถึง Theta (log (n)) ซึ่งหมายถึง "เติบโตเร็วเท่าlog(n)" en.wikipedia.org/wiki/…
Džuris

4
<pedantic> คุณไม่ได้เปลี่ยนเวลาในการประมวลผลของฟังก์ชั่น ฟังก์ชั่นคือความสัมพันธ์ระหว่างโดเมนและโคโดเมนและมีอยู่โดยไม่ขึ้นอยู่กับความพยายามของคุณในการติดตั้ง คุณพบอัลกอริทึมที่มีประสิทธิภาพดีกว่าซึ่งใช้ฟังก์ชัน </pedantic> <human> งานที่ดี </human>
emory

5
@Theonlygusti: มันขึ้นอยู่กับ หากก่อนหน้านี้ฟังก์ชั่นทำการรับประกัน / รับประกันความซับซ้อนแสดงว่าไม่ได้ทำการปรับเปลี่ยนใหม่ หากไม่รับประกันสิ่งใดเลยก็เป็นการสร้างใหม่ ถ้ามันชัดเจนเกี่ยวกับการไม่รับประกันมันเป็น refactoring โดยเฉพาะอย่างยิ่ง
phresnel

คำตอบ:


44

มันเป็นเรื่องปกติที่เรียกว่า"การเพิ่มประสิทธิภาพ"แต่ฉันจะไม่เรียกว่า "refactoring" เนื่องจากในระยะนี้มักจะหมายถึงการเปลี่ยนแปลงในรหัสที่ไม่เปลี่ยนแปลงของพฤติกรรมที่มองเห็นได้ และการเปลี่ยนแปลงใน Big-O เป็นสิ่งที่ฉันจะเรียกการเปลี่ยนแปลงที่มองเห็นได้อย่างแน่นอน

ในการทำเช่นนั้นฉันจะเปลี่ยนวิธีพื้นฐานในการดำเนินการ

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

แก้ไข: ฉันจะตรวจสอบรายชื่อ refactoring พรานล่าสัตว์และในหมู่นี้ ~ 100 refactorings ชื่อคนสุดท้ายมากเรียกว่า"แทนขั้นตอนวิธีการ" ดังนั้นหากเราใช้สิ่งนี้เป็นข้อมูลอ้างอิงแบบบัญญัติมีพื้นที่สีเทาขนาดเล็กที่การเพิ่มประสิทธิภาพของแบบฟอร์มที่อธิบายไว้อาจเรียกว่าการปรับโครงสร้างพิเศษชนิดใหม่ (แต่ IMHO ไม่ใช่แบบทั่วไป) ทราบด้วยว่าเป้าหมายของพรานล่าสัตว์ที่มีการปรับโครงสร้างทั้งหมดนั้นมักจะปรับปรุงการออกแบบโดยมุ่งเน้นที่การบำรุงรักษาและการวิวัฒนาการของรหัสที่มีอยู่โดยไม่ต้องเขียนใหม่และไม่ได้เพิ่มประสิทธิภาพการทำงานอย่างชัดเจน


10
จริงๆ? ฉันคิดว่าการเปลี่ยนโครงสร้างถูกต้องเว้นแต่ว่าข้อกำหนดจะเปลี่ยน ดังนั้น .. ไม่ถ้าฟังก์ชั่นนั้นเรียกว่า BubbleSort แต่ใช่ถ้ามันเป็นแค่ Sort
Ewan

3
@Ewan ใช่การรีฟอร์เรชั่นตามกฎหมายอาจเป็นการเพิ่มประสิทธิภาพ แต่อย่างใดอย่างหนึ่งในอดีตนั้นกว้างเกินไปและไม่ได้รับผลกระทบจากการเปลี่ยนแปลงที่เหมาะสม
Deduplicator

1
ฉันอยู่ที่การนำเสนอต้นโดยคนที่คิดค้นและประดิษฐ์ Refactoring (Fowler?) และความคิดทั้งหมดนั้นเชื่อมโยงกับการเขียนโปรแกรมอัตโนมัติและการปรับปรุงที่พิสูจน์ยืนยันได้ของโค้ดที่ไม่มีผลต่ออินพุตและเอาต์พุต
Sentinel

1
@ Steve ตกลง ฉันแค่เพิ่มความเห็นพ้องว่าการปรับปรุง Big O เป็นการปรับปรุงอัลกอริทึมไม่ใช่การปรับปรุงวิธีการแสดงหรือบำรุงรักษาอัลกอริธึมเหล่านั้น กล่าวอีกนัยหนึ่งกิจกรรมคือการเขียนซ้ำ
Sentinel

1
@ Steve: ใช่ฉันรู้ว่าคิดเกี่ยวกับการเพิ่มบันทึกคำตอบของฉัน การแก้ไขของฉันเป็นเพียงบันทึกเพื่อให้ชัดเจนว่ามีพื้นที่สีเทาขนาดเล็ก
Doc Brown

13

ฉันไม่คิดว่ามีคำศัพท์มาตรฐานที่ใช้กันทั่วไปคือการปรับให้เหมาะสมแม้ว่าการปรับปรุงหรือการเร่งความเร็วก็จะถูกต้องทำให้การชี้แจงว่าคุณกำลังพูดถึงการเปลี่ยนแปลงรหัสและไม่ใช่การเปลี่ยนแปลงฮาร์ดแวร์


7

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

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


5

มันจะขึ้นอยู่กับบริบท

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

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

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

ข้อร้องเรียนจากลูกค้าจำนวนมากเกี่ยวกับประสิทธิภาพของซอฟต์แวร์แบ่งออกเป็นสองประเภท:

  • ระบบทั้งหมด (ซอฟต์แวร์และฮาร์ดแวร์) ถูกระบุตามการใช้งานโดยประมาณ เมื่อสัปดาห์ที่แล้วทุกอย่างทำงานได้ดีฟังก์ชั่นบางอย่างใช้เวลาน้อยกว่า 5 วินาที ในสัปดาห์นี้หลังจากติดตั้งการปรับปรุงฟังก์ชั่นเดียวกันนี้ใช้เวลามากกว่า 1 นาที

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

    • ลูกค้าคาดว่าเวลาในการประมวลผลจะเป็นแบบเชิงเส้น ในความเป็นจริงลูกค้าไม่สามารถเข้าใจหรือยอมรับว่ามีงานที่ช้ากว่าเชิงเส้น

ด้วยเหตุผลนี้ลูกค้าจะถือว่าเวลาดำเนินการเป็นข้อผิดพลาดหากทั้งสองเป็นจริง:

  • ช้ากว่าเชิงเส้น
  • สามารถสังเกตได้ (เช่นอยู่ในช่วงเวลาของมนุษย์ (นานกว่าวินาทีหรือนาที) ตามขนาดงานทั่วไป)

ข้อโต้แย้งที่ถูกต้องตามกฎหมายที่อธิบายว่าอัลกอริทึมรันไทม์กำลังสองไม่ก่อให้เกิดปัญหา (เช่นไม่สมควรเปลี่ยนรหัส):

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

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

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


2

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

หากความซับซ้อนของเวลาก่อนหน้านี้เกิดจากข้อผิดพลาดในการนำไปใช้ (เช่นบอกว่าคุณตั้งใจรีเซ็ตจุดเริ่มต้นของลูปด้านในตามลำดับเพื่อให้สิ่งที่ควรเป็น O (n) กลายเป็น O (n 2 )) " ข้อผิดพลาดค่าใช้จ่ายกำลังสอง "หรือคล้ายกัน

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


1

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

ปรับปรุงความสามารถในการขยาย ได้ยินด้วย

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