คุณควรลดการสร้างวัตถุขนาดเล็กจำนวนมากหรือไม่


10

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

ฉันมีตัวอย่างที่แสดงความคิดนี้ได้ดี drawPixel(Point)ในโปรแกรมกราฟิกบอกว่ามีวิธีการที่จะใช้สำหรับการวาดภาพทั้งหมดที่เรียกว่านึกคิด อาจมีการสร้างคะแนน 1,000 คะแนนและอาจเกิดซ้ำบ่อยเช่นในเกมที่สามารถเรียก 60+ ครั้งต่อวินาที หรือdrawPixel(int x, int y)อาจใช้เพื่อลดการสร้างออบเจ็กต์ Point จำนวนมาก

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


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

@Snowman ฉันได้ยินมาว่า Java เวอร์ชั่นใหม่ทำได้ดีกว่ากับการจัดการหน่วยความจำ แต่ปัญหาที่ฉันเห็นคือไม่มีการรับประกันว่าผู้ใช้จะไม่ใช้เวอร์ชั่นที่เก่ากว่า นั่นเป็นส่วนหนึ่งของสิ่งที่สร้างความกังวลให้กับฉัน
Stripies

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

2
@Stripies ประสิทธิภาพของวัตถุ Java อายุสั้นตอบแล้วในเราควรหลีกเลี่ยงการสร้างวัตถุใน Java? . อย่างไรก็ตามหากคุณต้องจัดการกับวัตถุดังกล่าวหลายร้อยล้านต่อวินาทีเท่านั้น ณ จุดนั้นจะพิจารณาปัญหานี้อีกครั้ง
rwong

1
หากคุณกังวลเกี่ยวกับ Java เวอร์ชันเก่าให้ตรวจสอบเมื่อคุณติดตั้ง JVM เก่าพอที่จะทำให้เกิดปัญหากับการจัดการหน่วยความจำยังมีปัญหาด้านความปลอดภัยที่เป็นที่รู้จักเช่นกัน System.getProperty("java.version")(หรือ "java.vm.version") เป็นจุดเริ่มต้น
Jerry Coffin

คำตอบ:


17

โดยทั่วไปไม่คุณไม่ควรหลีกเลี่ยงการสร้างวัตถุเพราะกลัวการสูญเสียประสิทธิภาพ มีเหตุผลหลายประการนี้.

  1. การใช้อ็อบเจกต์เป็นจุดที่ใช้จาวา การหลีกเลี่ยงสิ่งเหล่านี้ถือเป็นสัญญาณบ่งชี้ว่าการตัดสินใจใช้ Java อาจไม่ใช่สิ่งที่ถูกต้องที่จะเริ่มต้นด้วย
  2. ปัญหาเรื่องประสิทธิภาพเป็นเรื่องยากที่จะคาดเดาได้ยาก อย่าคิดเลยว่าบางสิ่งเป็นคอขวด วัดทุกครั้ง วิศวกรรมประสิทธิภาพเป็นเรื่องของการเปลี่ยนแปลงเพียงเล็กน้อยในที่ที่ถูกต้อง คุณไม่สามารถทำนายสถานที่ที่เหมาะสมได้โดยไม่ต้องทำการวัดใด ๆ เกินกว่าที่คุณจะคาดการณ์ผลกระทบของยาโดยไม่ต้องทำการทดสอบ
  3. ค่าใช้จ่ายในการสร้างวัตถุสูงเกินไป ใน JVM ที่ทันสมัยนั้นมีจำนวนเพิ่มขึ้นตามตัวชี้ (และด้วยการสะสมขยะทั่วไป, ค่าใช้จ่ายในการจัดการมันก็เป็นเรื่องเล็กน้อย) มีข้อความมากมายบนอินเทอร์เน็ตที่แนะนำให้คุณหลีกเลี่ยงวัตถุการใช้การรวมวัตถุ ฯลฯ บางครั้งคำแนะนำนี้ถูกต้องในปี 1990; วันนี้มันล้าสมัยเป็นส่วนใหญ่ คุณไม่น่าจะได้รับประสิทธิภาพเพียงพอที่จะพิสูจน์ต้นทุนการพัฒนาและความซับซ้อนที่เพิ่มขึ้นโดยหลีกเลี่ยง Objects หรือจัดการด้วยตนเอง

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

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


2

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

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

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

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


2

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

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

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

OOP เป็นความคิดที่ดีด้วยเหตุผลบางประการ เหตุผลเหล่านั้นไม่สามารถใช้ได้ในทุกสถานการณ์


ฉันเห็นด้วย แต่ฉันก็เห็นด้วยกับคนอื่น ๆ ว่าการทดสอบเป็นวิธีเดียวที่จะรู้ได้อย่างแน่นอน ตรวจสอบให้แน่ใจว่าคุณมีรายละเอียดการทำด้วยวิธีที่ง่าย / ชัดเจนก่อนที่จะปรับให้เหมาะสม ... แต่ฉันยอมรับว่าใหม่ยังคงเป็นปัญหา
Bill K

2

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

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

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


1

ง่ายมาก: หากคุณต้องการวัตถุขนาดเล็ก 1,000 ชิ้นคุณจะสร้างวัตถุขนาดเล็ก 1,000 ชิ้นและไม่ต้องกังวลกับมัน หากคุณต้องการวัตถุขนาดเล็ก 100 ชิ้นการสร้างวัตถุขนาดเล็ก 1,000 ชิ้นนั้นเป็นเรื่องโง่ - สร้างวัตถุที่คุณต้องการและไม่มาก

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

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