Big O สำคัญจริงๆหรือ?


17

ในสถาบันการศึกษาที่เลวร้ายที่สุดกรณีBig Oสอนทุกอย่างอื่น เปรียบเทียบกับความซับซ้อนของพื้นที่การวิเคราะห์เคสปกติความเรียบง่ายเหนือความซับซ้อน ฯลฯ

โดยเฉพาะอย่างยิ่งกับการเขียนโปรแกรมเกมและอุตสาหกรรมสิ่งที่สำคัญที่สุดและทำไม?

การอ้างอิงจะมีประโยชน์มาก


Big-O = การปรับให้เหมาะสม เอาฉันไปคิดออกว่าใหญ่ 0 คืออะไร
AttackHobo

12
Big-O ไม่ใช่ "การเพิ่มประสิทธิภาพ" Big-O เป็นรูปแบบของการวิเคราะห์ที่จะบอกคุณว่าอัลกอริทึมที่แตกต่างกันจะทำงานอย่างไรในแง่ของประสิทธิภาพเมื่อจำนวนขององค์ประกอบเพิ่มขึ้น ดูen.wikipedia.org/wiki/Big_O_notationสำหรับรายละเอียดเพิ่มเติม
ZorbaTHut

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

1
จำกฎของเมื่อถึงการเพิ่มประสิทธิภาพ: 1) อย่าทำมัน 2) (ผู้เชี่ยวชาญเท่านั้น) อย่าทำเลย
zaratustra

ก่อนอื่นบิ๊กโอสามารถใช้สำหรับพื้นที่หรือความซับซ้อนในการคำนวณดังนั้น "เหนือสิ่งอื่นใด" จึงไม่เป็นความจริง ประการที่สอง Big O มักจะง่ายกว่าในการคำนวณหาบางอย่างมากกว่าการวิเคราะห์เคสปกติและจะใช้เป็นการตรวจสอบทางจิตอย่างรวดเร็วว่าคุณกำลังทำอะไรผิดหรือเปล่า หากการวาดเทพดาใช้เวลา O (2 ^ n) คุณควรเลือกอัลกอริทึมที่ต่างออกไป หากคุณต้องการแนวทางการออกแบบซอฟต์แวร์ที่ใช้งานได้จริงให้มองหาแนวทางปฏิบัติของ SE มากกว่า CS CS เป็นทฤษฎีในธรรมชาติในขณะที่ SE จะขึ้นอยู่กับอุตสาหกรรม
Deleter

คำตอบ:


25

เช่นเดียวกับคำถามอื่น ๆเกี่ยวกับ "เส้นทางที่แท้จริงคืออะไร" นี่คือเครื่องมือทั้งหมดในกล่องเครื่องมือของคุณและมีกรณีที่ big-O สำคัญกว่าทุกอย่างและสถานที่ที่ไม่สำคัญ (tm)

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

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

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

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


8
นี้. สิ่งสำคัญคือต้องเข้าใจคุณลักษณะด้านประสิทธิภาพของรหัสของคุณ คุณไม่เคยรู้เลยว่านักออกแบบจะใช้อะไรที่คุณเพิ่มในแบบที่คุณไม่คาดคิดและจู่ๆโค้ดที่คุณคิดว่าจะต้องจัดการ 5 ไอเท็มกำลังจัดการ 5,000 รายการและการส่ง Ping 100 ครั้งต่อเฟรม คุณเพิ่มประสิทธิภาพนั้น คุณสามารถ? จริง ๆ แล้วมีกี่เหตุผล โปรไฟล์จะบอกคุณว่ามันช้าเพียงใดทำไมไม่ใช่ การรู้ความซับซ้อนจะบอกคุณว่าคุณต้องการเพิ่มประสิทธิภาพรหัสหรือแทนที่ด้วยสิ่งที่แตกต่าง
JasonD

3
ตกลง มหาวิทยาลัยสอนให้คุณรู้จัก 'Big-O' เพราะมันจัดการกับปัญหามากมายที่คุณเผชิญ เมื่อคุณถูกถามว่า 'โอ้เราสามารถสร้างจำนวนอนันต์นี้ได้มากกว่าแค่ 5? ผู้ทดสอบเกลียดข้อ จำกัด 'นั่นคือเมื่อการฝึกอบรมดำเนินไป คุณไม่ควรพูดว่า 'ไม่ฉันไม่สามารถ' มันเป็นสิ่งสำคัญที่จะสามารถแก้ปัญหาจากสิ่งนั้นและพูดว่า 'ใช่ฉันทำได้' เกมของคุณต้องการกาแลคซีที่ค้นหาได้หรือไม่ 'ไม่มีปัญหา'. จำเป็นต้องสั่งซื้อล้านหน่วยเหล่านั้นหรือไม่ 'ไม่มีปัญหา'. 'ไม่ได้ศึกษาว่าเพียงพอ' เพียงแค่ไม่ตัดมัน
Rushyo

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

โจแน่นอนว่านั่นเป็นข้อกังวลที่แตกต่าง คุณต้องการ O (1) ที่มีค่าคงที่ที่สูงหรือ O (n) ที่มี 'n' และค่าคงที่ต่ำหรือไม่? การรู้จัก big-O ในกรณีนี้ไม่ใช่ปัญหา แต่สามารถช่วยให้คุณทราบว่าโซลูชันนั้นเหมาะสมกับสถานการณ์ที่จะใช้หรือไม่
dash-tom-bang

13

กฎง่ายๆของฉันคือถ้าคุณไม่ใช่ O (น่ากลัว) ปัญหาอื่น ๆ ของคุณจะเกี่ยวข้องมากขึ้น

กฎง่ายๆอีกข้อคือว่าข้อมูลนั้นเป็นราชา ถ้าคุณไม่ทำโปรไฟล์ของคุณด้วยชุดข้อมูลที่เป็นจริงคุณก็แค่เดา

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


8

Big O ใช้เวลาส่วนใหญ่ แต่บางครั้งอัลกอริทึม "แย่ลง" ในทางทฤษฎีกลับกลายเป็นว่าเร็วขึ้นในทางปฏิบัติ

ลองดูตัวอย่างดีๆจาก Tony Albrecht: http://seven-degrees-of-freedom.blogspot.com/2010/07/question-of-sorts.html

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

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

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


"ปัญหากับ Big O" คือคนดูเหมือนจะลืมว่ามันเป็นความซับซ้อนของอัลกอริทึมประสิทธิภาพ WRT เทียบกับชุดข้อมูลขนาดใหญ่ ในเกมเรามักจะไม่ตีค่าของ N ดังนั้นเราจึงจำเป็นต้องกังวลเกี่ยวกับชิ้นส่วนอื่นของตัวต่อ ฉันสงสัยว่าการเรียงลำดับฟองจะดีกว่าการเรียงลำดับอย่างรวดเร็วเสมอเมื่อคุณมีรายการองค์ประกอบสองรายการ
dash-tom-bang

7

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

ในกรณีนี้ฉันไม่เกี่ยวข้องกับ big-O มากเท่าที่ฉันกังวลกับตัวคูณตัวคูณคงที่และคำสั่งซื้อที่ต่ำกว่า สำหรับฟังก์ชั่นที่มีรันไทม์เช่นa*n^2 + b*n + c(ซึ่งเป็นO(n^2)) ผมมักจะกังวลมากขึ้นด้วยการลดและอาจจะกำจัดa cค่าติดตั้งหรือค่าการฉีกขาดcnอาจจะกลายเป็นเมื่อเทียบกับขนาดใหญ่ตามสัดส่วนที่มีขนาดเล็ก

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

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

ในการให้ตัวอย่างที่เฉพาะเจาะจง: สิ่งนี้หลุดมือไปแล้วด้วยอัลกอริธึมสตรีมเรียงภาพไทล์พื้นหลังซึ่งสตรีมแบบเรียงต่อกันขนาด 8x8 256 สี การใช้บัฟเฟอร์การสตรีมมิ่งร่วมกันระหว่าง "เลเยอร์" ในพื้นหลังและเราอาจมีมากถึง 6 รายการในระดับที่กำหนดซึ่งแบ่งใช้บัฟเฟอร์เดียวกัน ปัญหาคือการประมาณขนาดของบัฟเฟอร์ที่ต้องการนั้นขึ้นอยู่กับตำแหน่งที่เป็นไปได้ของทั้ง 6 เลเยอร์ - และหากพวกเขามีอัตราความกว้าง / ความสูง / สกรอลล์จำนวนเฉพาะจำนวนมากคุณจะเริ่มค้นหาอย่างละเอียด เริ่มเข้าใกล้O(6^numTiles)- ซึ่งอยู่ในหมวดหมู่ "นานกว่าเอกภพ" โชคดีที่กรณีส่วนใหญ่เป็นเพียง 2-3 เลเยอร์ แต่ถึงอย่างนั้นเราก็มีเวลารันไทม์ครึ่งชั่วโมง ในขณะนี้เราสุ่มตัวอย่างย่อย ๆ น้อย ๆ ของความเป็นไปได้เหล่านี้เพิ่มความละเอียดจนกว่าจะถึงเวลาที่กำหนด (หรือเราได้ทำงานให้เสร็จซึ่งอาจเกิดขึ้นสำหรับการกำหนดค่าเลเยอร์สองชั้นเล็ก ๆ ) เราชนประมาณนี้ขึ้นอยู่กับสถิติก่อนหน้านี้ว่าเราได้รับการพิสูจน์แล้วว่าผิดบ่อยแค่ไหนและจากนั้นเพิ่มช่องว่างเสริมเล็กน้อยเพื่อการวัดที่ดี

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

(ฉันมักจะพบว่าอัลกอริธึมไร้เดียงสานั้นมีค่าสูงกว่าบิ๊กโอเร็วกว่าในชุดข้อมูลขนาดเล็กและง่ายต่อการเข้าใจยิ่งซับซ้อน / ซับซ้อนมากขึ้น (เช่น patricia trie) ยากสำหรับคนที่จะเข้าใจและบำรุงรักษา ชุดข้อมูล)


4

มันอาจมีประโยชน์ แต่ก็อาจไม่เกี่ยวข้องด้วย ยกตัวอย่างเช่นเกมล่าสุดของฉันซึ่งเป็นเกมโคลนของ Smash TV เกมบนลงล่าง, มอนสเตอร์เทลงมาจากด้านข้างคุณยิงพวกเขา

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

แต่ฉันรู้สึกขี้เกียจฉันจึงเปรียบเทียบกระสุนทั้งหมดกับสัตว์ประหลาดทุกตัว แม้แต่ในสถานการณ์ที่วุ่นวายที่สุดรหัสการชนกันก็ใช้ซีพียูเกมน้อยกว่า 10% ที่ 60fps Big-O: ไม่สำคัญ

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

Big-O นั้นมีความสำคัญในเกมเช่นเดียวกับที่มีในทุกสิ่ง: กล่าวคือไม่สำคัญจนกระทั่งกลายเป็นสิ่งสำคัญ

ไปเขียนโค้ด ถ้ามันช้าเกินไปให้ทำโพรไฟล์


3

การวิเคราะห์ Big-O มีความสำคัญ แต่ไม่ใช่สิ่งแรกที่ต้องคำนึงถึงในการพัฒนาเกม เนื่องจากการทำเกมเกี่ยวข้องกับรหัสที่ซับซ้อนจำนวนมากฉันมักจะแนะนำCode Simplicityเป็นเกณฑ์แรกสำหรับอัลกอริทึม อัลกอริทึมที่มีการทำบัญชีที่ซับซ้อนเพียงเสียเวลา

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

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

  1. ตรวจสอบให้แน่ใจว่าคุณไม่ได้โทรหาใหม่หรือ malloc แต่ละเฟรม (นี่เป็นปัญหา # 1 เสมอ)
  2. ลดการทำงาน: ปล่อยรังสีน้อยลง, ลดน้อยลง, ฯลฯ
  3. ปัญหาประเภทอัลกอริทึม Big-O
  4. การเชื่อมโยงกันแคช: ใส่สิ่งต่าง ๆ ในอาร์เรย์มากกว่าหน่วยความจำกระจัดกระจาย
  5. อย่าใช้ STL ในโหมดแก้ไขข้อบกพร่อง (และคุณต้องการให้โหมดดีบั๊กทำงานเสมอ)

2

สัญกรณ์ Big-O เป็นการนิยามความซับซ้อนแบบอะซิมโทติคกล่าวคือมันแสดงให้เห็นว่าเวลาปรับขนาดอย่างไรเมื่อ N (หรือตัวแปรใดก็ตามที่คุณมี) ได้รับขนาดใหญ่มาก หากต้องการแสดงความคิดเห็นของ Tetrad อีกครั้ง (ซึ่งฉันเพิ่มขึ้น) "data is king" ถ้า N เป็น "ใหญ่มาก" ในสถานการณ์เฉพาะของคุณมันสำคัญถ้า N คือ "เล็กมาก" มันไม่สำคัญ ประสบการณ์และการฝึกฝนจะทำให้คุณรู้สึกถึงวิธีการหาจำนวน "มาก" และ "เล็กมาก"

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


1

ความสำคัญของ Big-O ในซอฟต์แวร์ของคุณคือ O (N 2 ) เมื่อ N เติบโตขึ้นความสำคัญของการมีอัลกอริธึมที่เหมาะสมยิ่งเพิ่มมากขึ้น :)


นั่นไม่ได้ขึ้นอยู่กับความถี่ที่อัลกอริทึมนั้นถูกเรียก ..
bobobobo

ในระดับหนึ่ง แต่ถ้าใช้เวลา 3 วันจึงอาจไม่สำคัญว่าคุณจะเรียกมันครั้งเดียวเท่านั้น :)
Kylotan

1

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

1) หากคุณมีอัลกอริธึมสองตัวที่ทำสิ่งเดียวกัน แต่ส่วนใหญ่มี O ดีกว่าคุณอาจจะไปหามัน (ชัด ๆ )

2) Big O เป็นกังวลกับการวิเคราะห์เชิง Big-O จะเข้ามาเล่นเมื่อ n มีขนาดใหญ่เท่านั้น ตัวอย่างเช่น O (n) ขั้นตอนวิธีการอาจจะคล้ายกันมากในการทำงานให้กับ O (n ^ 2) หนึ่ง .. สำหรับ n หากคุณกำลังพูดถึงอัลกอริทึมที่ต้องใช้การดำเนินงาน n ^ 2 ต่อจุดสุดยอด แต่ n = 2 หรือ n = 3 แสดงว่าไม่มีความแตกต่างระหว่างอัลกอริทึม O (n ^ 2) (ใช้ 4 และ 9 ops resp) และ O (n) หนึ่ง (2 และ 3 ตัวเลือก) อย่างไรก็ตามถ้า n = 9 คุณก็กำลังพูดถึง 81 การดำเนินงานสำหรับอัลกอริทึม O (n ^ 2) และเพียง 9 สำหรับ O (n) หนึ่ง - ความแตกต่างที่ใหญ่กว่า - และถ้า n = 100 คุณก็จะ พูดคุยเกี่ยวกับ 100 ops กับ 10,000 - ความแตกต่างที่ใหญ่กว่ามาก

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


0

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


0

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

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

อย่าเหงื่อมัน


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

ต้นแบบของการพัฒนาเกมมีเปอร์เซ็นต์เท่าใด ในที่สุดคุณต้องการที่จะจัดส่งบางสิ่งบางอย่างใช่มั้ย?
dash-tom-bang

0

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

ฉันคิดว่ามันใช้กับเกมมากกว่าอุตสาหกรรมอื่น ๆ ส่วนใหญ่เนื่องจากตลาดเป็นผู้หนึ่งที่จะสังเกตเห็นปัญหาความเร็วมากที่สุด บางคนที่ใช้โปรแกรมประมวลผลคำจะไม่สนใจว่ามีความล่าช้าครึ่งวินาทีในการทำ Action X แต่ผู้เล่นอาจจะไป 'omg omg game Y ช้ามากมันต้องใช้เวลานานกว่าจะทำงานได้ Z'


0

ในการพัฒนาเกม (และอื่น ๆ ส่วนใหญ่) เรากำลังคร่ำครวญเกี่ยวกับการดำเนินการพิเศษหนึ่งอย่างที่ดำเนินการต่อลูป:

for (int i = 0; i < array.length; i ++) { /* ... */ }

เมื่อเทียบกับ

for (int i = 0, l = array.length; i < l; i ++) { /* ... */ }

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

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

ในอัลกอริทึมการตรวจจับการชนกันแบบดั้งเดิมความซับซ้อนของเวลาคือ O (n ^ 2) เช่นเดียวกับ n-body อย่างไรก็ตามมีวิธีที่ดีกว่า: แยกโลกออกเป็นชิ้นส่วนเล็ก ๆ หลายชิ้นดังนั้นวัตถุที่อยู่ในส่วนเดียวกันเท่านั้นที่จะถูกตรวจจับการชนกัน ดูhttp://www.videotutorialsrock.com/opengl_tutorial/collision_detection/text.php

หากเกมของคุณเป็นสคริปต์อย่าเขียน Scripter เขียน O (n ^ 2) (และสูงกว่า) อัลกอริทึมการบีบอัดตัวเลขในสคริปต์เช่นการค้นหากระเป๋าของผู้ใช้ ทำให้ฟังก์ชั่นที่มีอยู่ในรหัสแทน


1
ตัวอย่างรหัสของคุณทั้งสองคือ O (n) การสนทนา Big-O ไม่มีส่วนเกี่ยวข้องกับ "การทำงานพิเศษหนึ่งครั้งต่อการวนซ้ำ" แต่เป็นการ "การค้นหาพิเศษหนึ่งครั้งผ่านการทำซ้ำทุกอย่างต่อการวนซ้ำของทุกสิ่ง"
dash-tom-bang

-2

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

นอกจากนี้เนื่องจากทิศทางปัจจุบันในแพลตฟอร์มและสถาปัตยกรรมแบบมัลติเธรด Big-O จึงสูญเสียความสำคัญอย่างมากเนื่องจากคำนึงถึงความสามารถในการปรับขนาดตามแนวตั้งของหน่วยความจำหรือข้อมูลที่สัมผัสต่อการดำเนินการแทนที่จะคำนึงถึงวิธีอัลกอริธึม สเกลที่มีจำนวนเธรดที่มากกว่า


3
สิ่งนี้ไม่ถูกต้องสัญลักษณ์ Big O ใช้เพื่อแสดงขอบเขตบนของอัลกอริธึมแบบขนานเหมือนกับอัลกอริธึมเชิงเส้น Big O สามารถใช้สำหรับสถาปัตยกรรมการเขียนแบบอ่าน / พร้อมกันเป็นต้นคุณสามารถทำสิ่งที่บ้าคลั่งเช่นการเรียงลำดับใน O (1) พร้อมตัวประมวลผล n ^ 2
David Young

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

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

การเรียงลำดับในตัวประมวลผล O (1) กับตัวประมวลผล n ^ 2 ไม่ใช่ตัวอย่างที่ดีที่สุดสัญกรณ์ Big-O ประเภทนี้น่าจะเห็นได้บ่อยที่สุดในสถาบันการศึกษา บางอย่างเช่นนี้cs.bu.edu/~best/crs/cs551/homeworks/hw1/pram.htmlอัลกอริทึมแบบขนานที่สมจริงยิ่งขึ้นสามารถใช้ตัวประมวลผล log (n) ประเภทของสิ่งนี้เหมาะสำหรับการใช้งานเกินกำลังในการประมวลผล GPU หรือการประมวลผลขั้นสูงที่มีหลายร้อยคอร์
David Young Young

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