รหัสใดในสองรหัสนี้ที่ 'ดีกว่า' ทำให้ตัวแปรท้องถิ่นหรือตัวแปรคลาส?


11

ฉันสร้างเกมมากขึ้นและถามคำถามที่โง่กว่านี้

หวังว่าอันนี้จะสั้นมาก ฉันกำลังสร้างคลาสพื้นฐานที่เพิ่งย้ายวัตถุ Player โดยใช้กำลังกับคนที่แข็งทื่อ แต่มันทำให้ฉันสงสัยว่าฉันควรจะอ้างอิงคลาสกับ rb หรือเพียงแค่ตัวแปรท้องถิ่นในอัปเดตทุกเฟรมหรือไม่ (จำไว้ว่ามันมีอยู่แล้วใน Monobehaviour.GameObject ระดับผู้ปกครองสามัคคี)

ฉันสงสัยว่าถ้าทำหลายตัวแปรในท้องถิ่นจะทำให้วงทั้งหมดช้าลง (โดยเฉพาะที่ฉันหมายถึงในฟังก์ชั่นของตัวเองไม่ใช่ในชั้นเรียน - หวังว่าฉันจะใช้คำศัพท์ที่ถูกต้อง)

นี่คือสิ่งที่ฉันหมายถึงสองวิธีที่ฉันคิดทำ:

public class Player : MonoBehaviour {

private void FixedUpdate()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

หรือ...

public class Player : MonoBehaviour {
Rigidbody rb;

private void Awake()
{
    rb = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

4
ดูเหมือนว่าจะเป็นคำถามเพิ่มเติมสำหรับการตรวจสอบรหัส SE
Orphevs

1
คุณสามารถสร้างคุณสมบัติคลาส float va
ชาด

ในที่สุดฉันก็อาจจะชาดจริง ๆ เพราะฉันจะใช้มันในสองวิธีในชั้นเรียน เป็นรหัสง่ายๆที่จะได้รับคำถามเกี่ยวกับตัวแปรระดับท้องถิ่นเทียบกับทั่วโดยไม่ bloating ออกด้วยรหัสจำนวนมาก ฉันชอบเก็บตัวแปรไว้ในเครื่อง (และ 'ไปให้พ้นทาง'!) แต่แน่นอนฉันต้องแน่ใจว่าฉันไม่เริ่มทำสิ่งต่าง ๆ แทนการมีตัวแปรระดับหนึ่งสำหรับแต่ละคน
Big T Larrity

ตัวอย่างโค้ดไม่ใช่ 'a code' การถามว่า 'โค้ดไหนดีกว่า' ทำให้คุณดูเหมือนมือสมัครเล่น
Miles Rout

1
ฉันเป็นมือสมัครเล่นดังนั้นก็ดีกับฉันขอบคุณ Miles
Big T Larrity

คำตอบ:


25

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

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

การประกาศตัวแปรท้องถิ่นเพียงอย่างเดียวจริงๆแล้วจะไม่เกี่ยวข้องกับประสิทธิภาพในทางปฏิบัติจริง: ราคาถูกและคอมไพเลอร์สมัยใหม่อาจเพิ่มประสิทธิภาพ "ความพิเศษ" ออก

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

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

ดังนั้นเพื่อสรุป: โดยทั่วไปค่าเริ่มต้นในการทำสิ่งต่าง ๆ ในท้องถิ่นเป็นไปได้ แต่ในกรณีนี้มันอาจจะสมเหตุสมผลในการสร้างrbสมาชิกเพื่อให้คุณสามารถทำการค้นหาครั้งเดียวAwakeและหลีกเลี่ยงการFixedUpdateโทรทุกครั้ง


1
ขอบคุณ Josh ฉันรู้สึกว่ามันจะดีกว่าถ้ามีการเริ่มต้น rb เพียงครั้งเดียวและขอบคุณมากสำหรับการอธิบายอย่างชัดเจนว่าทำไม มันเป็นเรื่องดีที่จะรู้แน่นอนคุณเห็นว่าฉันไม่แน่ใจ 100% ว่า GetComponent นับว่าเป็นการเริ่มต้นแต่ละครั้งหรือเพียงแค่ 'ค้นหามัน' จาก Monobehaviour แต่ตอนนี้ฉันได้รับแล้วขอบคุณมากสำหรับคำตอบที่เป็นประโยชน์อย่างรวดเร็ว
Big T Larrity

1
@SuperMegaBroBro GetComponent นั้นค่อนข้างเร็ว - คุณต้องกดอย่างหนักทำให้การค้นหาชนิดใดที่มีความเร็วใกล้เคียงกัน หากคุณไม่มีข้อมูลประสิทธิภาพที่บ่งบอกว่าเป็นปัญหาให้ใช้วิธีการ "รักษาทุกสิ่งในท้องถิ่น" คุณสามารถเพิ่มประสิทธิภาพได้ในภายหลัง ดูanswer.unity.com/questions/185164/…อย่าลืมว่าการแคชไม่ฟรีเช่นกัน - ถ้าคุณแคชทุก ๆGetComponentเกมของคุณมันอาจจะเป็นผลขาดทุนสุทธิ วัด. ระบุว่าการเพิ่มประสิทธิภาพนั้นคุ้มค่าหรือไม่ มุ่งเน้นไปที่การสร้างเกมที่ยอดเยี่ยม :)
Luaan

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

ขอบคุณพวกคุณมากโดยเฉพาะอย่างยิ่ง Luaan เนื่องจากฉันสงสัยเกี่ยวกับปัญหา 'แคช' ในขณะที่ฉันเขียนคำถามดั้งเดิม (แต่ฉันไม่รู้วิธีการใช้คำนั้นจริงๆ) แน่นอนฉันจะใช้วิธี 'ท้องถิ่น' มากที่สุด ขอบคุณสำหรับความช่วยเหลือที่ยอดเยี่ยมเหมือน fellas ปกติ
Big T Larrity

2

คำตอบของ Josh Petrie นั้นดีมาก - นี่เป็นมุมมองที่สมบูรณ์

เมื่อคุณทำงานกับรหัสที่คุณเข้าใจโดเมนค่อนข้างดีคุณสามารถกำหนดขอบเขตตัวแปรให้เหมาะสม

ตัวอย่างเช่นถ้าฉันมีPersonระดับด้วยwaveGoodbyeวิธีการก็เป็นไปได้ว่าชั้นเรียนของฉันไม่ได้มีวัตถุก่อนและเพื่อให้ฉันสามารถประกาศในท้องถิ่นhand waveGoodbyeตอนนี้ที่นี่เห็นได้ชัดว่าคน ๆ หนึ่งมีมือดังนั้นคุณอาจประกาศโดยธรรมชาติในฐานะสมาชิกคนหนึ่งPersonโดยไม่ต้องคิดถึงมัน แต่ก็มีปัญหาเดียวกัน

หากคุณประกาศhandภายในเครื่องในภายหลังคุณอาจเพิ่มkarateChopวิธีที่ต้องใช้มือ นี่คือเมื่อการประกาศตัวแปรในเครื่องสามารถกลายเป็นปัญหาได้ - เนื่องจากผู้พัฒนารุ่นน้องมักจะถอยกลับเพื่อคัดลอก / วางการประกาศจากwaveGoodbyeและตอนนี้คุณมีแนวคิดเดียวกันอยู่ในสองจุด การเปลี่ยนแปลงใด ๆ ที่จะhandต้องมีการแก้ไขในทั้งสองสถานที่และจึงเริ่มต้นด้วยมดบั๊ก

ดังนั้นทั้งหมด

  1. หากคุณมั่นใจในตำแหน่งของการประกาศของคุณให้กำหนดขอบเขตไปยังตำแหน่งที่เหมาะสม

  2. หากคุณไม่มั่นใจให้เริ่มต้นระบบในพื้นที่และตรวจสอบให้แน่ใจว่าได้ปรับโครงสร้างใหม่เมื่อคุณได้รับการนำรหัสมาใช้ซ้ำ

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


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

1
คำตอบที่ดีขอบคุณพวก ฉันไม่ได้พยายามที่จะฟังดูเหมือนรู้ แต่คำตอบทั้งหมดเหล่านี้เพิ่งยืนยันสิ่งที่ฉันคิดอยู่แล้วดังนั้นเมื่อฉันมีความสุขมากและมีความคืบหน้าในเกมของฉัน ตอนนี้ฉันกำลังสร้างเกมฟุตบอล 3 มิติที่มีภาพเคลื่อนไหวที่เหมาะสมและทุกอย่างสร้างความก้าวหน้าอย่างแท้จริง: D เร็ว ๆ นี้ฉันจะมาที่นี่ต้องการความช่วยเหลือเกี่ยวกับวิธีทำให้ผู้เล่น 2 คนและกล้าพูดออนไลน์ mulitplayer: D ขอให้สนุกและขอบคุณอีกครั้ง!
Big T Larrity
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.