วันนี้ความเร็วของ Java เปรียบเทียบกับ C ++ อย่างไร
ยากที่จะวัด เป็นที่น่าสังเกตว่าส่วนสำคัญของความเร็วของการนำไปใช้งานนั้นเป็นตัวจัดสรรหน่วยความจำซึ่งเป็นอัลกอริธึมที่แตกต่างกันมากใน Java และ C ++ ลักษณะที่ไม่ได้กำหนดไว้ล่วงหน้าของตัวสะสมทำให้ยากมากที่จะได้รับข้อมูลประสิทธิภาพที่มีความหมายเมื่อเปรียบเทียบกับการจัดการหน่วยความจำแบบกำหนดค่าของ C ++ เนื่องจากคุณไม่สามารถมั่นใจได้เลยว่าสถานะตัวสะสมคืออะไรซึ่งหมายความว่าเป็นการยากมาก ที่อาจเปรียบเทียบความหมายกับพวกเขา รูปแบบการจัดสรรหน่วยความจำบางรูปแบบทำงานได้เร็วขึ้นด้วย GC บางรูปแบบทำงานได้เร็วขึ้นมากด้วยตัวจัดสรรดั้งเดิม
อย่างไรก็ตามสิ่งที่ฉันจะพูดคือ Java GC ต้องทำงานได้อย่างรวดเร็วในทุกสถานการณ์ อย่างไรก็ตามการปันส่วนแบบเนทีฟสามารถถูกสลับเป็นค่าที่เหมาะสมกว่าได้ ฉันเพิ่งถามคำถามเกี่ยวกับSOว่าทำไม C # Dictionary
สามารถทำงานใน (0.45 ms บนเครื่องของฉัน) เมื่อเทียบกับเทียบเท่าstd::unordered_map
ซึ่งทำงานบน (10ms บนเครื่องของฉัน) อย่างไรก็ตามโดยการแลกเปลี่ยนตัวจัดสรรและแฮ็กสำหรับตัวที่เหมาะสมกว่าฉันจะลดเวลาการดำเนินการนั้นเป็น 0.34 มิลลิวินาทีบนเครื่องของฉันซึ่งเท่ากับสามสิบปีของการทำงานเดิม คุณไม่เคยคาดหวังว่าจะทำการปรับให้เหมาะสมแบบนั้นกับ Java ตัวอย่างที่ดีของสิ่งที่สามารถสร้างความแตกต่างที่แท้จริงคือเกลียว ไลบรารีเธรดดั้งเดิมเช่น TBB มีตัวจัดสรรเธรดการแคชซึ่งเร็วกว่าตัวจัดสรรแบบดั้งเดิมอย่างมากเมื่อจัดการกับการจัดสรรจำนวนมากในหลายเธรด
ตอนนี้หลายคนจะพูดถึงการปรับปรุง JIT และวิธีที่ JIT มีข้อมูลเพิ่มเติม แน่นอนว่าเป็นเรื่องจริง แต่ก็ยังไม่ใกล้เคียงกับสิ่งที่คอมไพเลอร์ C ++ สามารถดึงได้เนื่องจากคอมไพเลอร์มีเวลาและพื้นที่ที่ไม่มีที่สิ้นสุดที่จะทำงานจากมุมมองของเวลาทำงานของโปรแกรมสุดท้าย ทุกรอบและทุก ๆ ไบต์ที่ JIT ใช้เวลาคิดว่าวิธีที่ดีที่สุดในการเพิ่มประสิทธิภาพโปรแกรมของคุณคือวงจรที่โปรแกรมของคุณไม่ได้ใช้จ่ายในการดำเนินการและไม่สามารถใช้สำหรับความต้องการของหน่วยความจำของตัวเอง
นอกจากนี้ยังมีบางครั้งที่การเพิ่มประสิทธิภาพของคอมไพเลอร์และ JIT ไม่สามารถพิสูจน์การเพิ่มประสิทธิภาพบางอย่างได้โดยเฉพาะในกรณีของสิ่งต่าง ๆ เช่นการวิเคราะห์การหลบหนี ใน C ++ นั้นเป็นค่าเป็นในกองอยู่แล้วคอมไพเลอร์ไม่จำเป็นต้องดำเนินการนั้น นอกจากนี้ยังมีสิ่งที่ง่ายเช่นความทรงจำที่ต่อเนื่องกัน หากคุณจัดสรรอาเรย์ใน C ++ คุณจะต้องจัดสรรอาเรย์เดี่ยวที่ต่อเนื่องกัน หากคุณจัดสรรอาเรย์ใน Java ก็จะไม่ต่อเนื่องกันเลยเพราะอาเรย์นั้นเต็มไปด้วยพอยน์เตอร์ที่สามารถชี้ได้ทุกที่ นี่ไม่เพียง แต่เป็นหน่วยความจำและค่าใช้จ่ายเวลาสำหรับการเปลี่ยนทิศทางแบบคู่ แต่ยังรวมถึงค่าใช้จ่ายแคชด้วย สิ่งนี้คือที่ความหมายของภาษาของ Java บังคับใช้ว่าต้องช้ากว่าโค้ด C ++ ที่เทียบเท่ากัน
ในที่สุดประสบการณ์ส่วนตัวของฉันคือ Java อาจจะประมาณครึ่งหนึ่งของความเร็วของ C ++ โดยเฉลี่ย อย่างไรก็ตามไม่มีวิธีใดที่จะสำรองข้อมูลงบประสิทธิภาพโดยไม่มีชุดมาตรฐานที่ครอบคลุมมากเนื่องจากอัลกอริทึมที่แตกต่างกันโดยพื้นฐานที่เกี่ยวข้อง
ข เป็นไปได้ไหมที่จะสร้างชื่อ AAA ที่ทันสมัยโดยใช้ Java?
ฉันคิดว่าคุณหมายถึง "เกม" ที่นี่และไม่ใช่โอกาส ประการแรกคุณต้องเขียนทุกอย่างตั้งแต่เริ่มต้นเพราะห้องสมุดและโครงสร้างพื้นฐานเป้าหมาย C ++ เกือบทั้งหมด ในขณะที่ไม่ทำให้มันเป็นไปไม่ได้ต่อหนึ่งครั้ง ประการที่สองแม้แต่เอนจิ้น C ++ ก็แทบจะไม่สามารถ จำกัด หน่วยความจำขนาดเล็กของคอนโซลที่มีอยู่ได้หาก JVMs ยังคงมีอยู่สำหรับผู้เล่นเกมคอนโซลเหล่านั้นและนักเล่นเกมพีซีคาดหวังมากขึ้นสำหรับหน่วยความจำ การสร้างเกม AAA นักแสดงนั้นยากพอใน C ++ ฉันไม่เห็นว่าจะสามารถทำได้ใน Java ไม่มีใครเคยเขียนเกม AAA ที่ใช้เวลาอย่างมากในภาษาที่ไม่ได้คอมไพล์ ยิ่งไปกว่านั้นมันอาจเป็นเรื่องที่ผิดพลาดได้ง่าย การทำลายล้างที่กำหนดได้นั้นเป็นสิ่งจำเป็นเมื่อต้องรับมือกับเช่นทรัพยากรของ GPU และในจาวาคุณ
ค Java ช้ากว่า C ++ เป็นพิเศษในด้านใดบ้าง? (เช่นการบีบตัวเลขกราฟิกหรืออื่น ๆ )
ฉันจะไปทุกอย่างแน่นอน ลักษณะการอ้างอิงแบบบังคับของออบเจ็กต์ Java ทั้งหมดหมายความว่า Java มีทิศทางที่ไกลกว่ามากและการอ้างอิงในนั้นมีค่ามากกว่า C ++ ตัวอย่างที่ฉันให้กับอาร์เรย์ก่อนหน้านี้ แต่ยังใช้กับออบเจ็กต์สมาชิกทั้งหมดด้วย ในกรณีที่คอมไพเลอร์ C ++ สามารถค้นหาตัวแปรสมาชิกในเวลาคงที่เวลาทำงานของ Java ต้องติดตามตัวชี้อื่น ยิ่งคุณเข้าถึงมากเท่าไหร่ก็ยิ่งช้าลงเท่านั้นและจะไม่มีอะไรที่ JIT สามารถทำได้
ที่ C ++ สามารถฟรีและใช้ชิ้นส่วนของหน่วยความจำใหม่ได้เกือบจะทันทีใน Java คุณต้องรอการรวบรวมและฉันหวังว่าชิ้นส่วนนั้นจะไม่ออกจากแคช จากนั้นดูความหมายของสิ่งต่าง ๆ เช่นการชกมวยและการไม่ทำกล่อง ใน Java หากคุณต้องการอ้างอิง int คุณจะต้องจัดสรรมันแบบไดนามิก นั่นเป็นของเสียโดยธรรมชาติเมื่อเทียบกับซีแมนทิกส์ C ++
แล้วคุณมีปัญหาเรื่องยาชื่อสามัญ ใน Java คุณสามารถทำงานกับวัตถุทั่วไปผ่านการสืบทอดมรดก ใน C ++ เทมเพลตมีค่าใช้จ่ายเป็นศูนย์อย่างแท้จริง - สิ่งที่ Java ไม่สามารถจับคู่ได้ นี่หมายความว่าโค้ดทั่วไปทั้งหมดใน Java นั้นช้ากว่าโค้ดทั่วไปใน C ++
และจากนั้นคุณมาที่พฤติกรรมที่ไม่ได้กำหนด ทุกคนเกลียดเมื่อรายการของพวกเขาจัดแสดง UB และทุกคนปรารถนาว่ามันจะไม่มีอยู่จริง อย่างไรก็ตาม UB เป็นพื้นฐานเปิดใช้งานการเพิ่มประสิทธิภาพที่ไม่เคยมีอยู่ใน Java ลองดูที่โพสต์นี้อธิบายการเพิ่มประสิทธิภาพตาม UB การไม่กำหนดพฤติกรรมหมายความว่าการใช้งานสามารถเพิ่มประสิทธิภาพได้มากขึ้นและลดรหัสที่จำเป็นในการตรวจสอบเงื่อนไขที่จะไม่ได้กำหนดใน C ++ แต่กำหนดไว้ใน Java
พื้นฐานความหมายของ Java บอกว่ามันเป็นภาษาที่ช้ากว่า C ++
ตอนนี้ Java ถือเป็นภาษาที่รวบรวมหรือแปลภาษาหรือไม่?
มันไม่เหมาะกับทั้งสองกลุ่ม ฉันว่าการจัดการเป็นหมวดหมู่แยกต่างหากของตัวเองถึงแม้ว่าฉันจะบอกว่ามันเป็นภาษาที่ตีความมากกว่าภาษาที่แปลแล้ว ที่สำคัญกว่านั้นมีเพียงสองระบบที่มีการจัดการที่สำคัญคือ JVM และ CLR และเมื่อคุณพูดว่า "มีการจัดการ" จะมีความชัดเจนเพียงพอ
อะไรคือข้อบกพร่องที่สำคัญของ Java ที่ได้รับการแก้ไขตั้งแต่ต้น?
มวยอัตโนมัติและ unboxing เป็นสิ่งเดียวที่ฉันรู้ ยาชื่อสามัญแก้ปัญหาบางอย่างแต่ห่างไกลจากหลาย ๆ
อะไรคือข้อบกพร่องที่สำคัญของ Java ที่ยังไม่ได้รับการแก้ไข?
ยาชื่อสามัญของพวกเขาอ่อนแอมาก ๆ ข้อมูลทั่วไปของ C # นั้นแข็งแกร่งกว่ามาก - ถึงแม้ว่าจะไม่มีเทมเพลตเลยทีเดียว การทำลายล้างตามกำหนดเป็นอีกหนึ่งการขาดที่สำคัญ รูปแบบของแลมบ์ดา / การปิดใด ๆ ก็เป็นปัญหาที่สำคัญเช่นกันคุณสามารถลืม API ที่ใช้งานได้ใน Java และแน่นอนว่ายังมีปัญหาเรื่องประสิทธิภาพอยู่เสมอสำหรับพื้นที่เหล่านั้นที่ต้องการ