Java ช้าจริงเหรอ?


180

Java มีการศึกษาระดับปริญญาบางส่วนของชื่อเสียงในการเป็นช้า

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

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

1
ฉันได้อ่านความคิดเห็นยอดนิยมส่วนใหญ่แล้วดูเหมือนว่าไม่มีใครตอบความจริงที่ว่าแอพพลิเคชั่นเดสก์ท็อปที่ใช้ C # GUI ทำงานได้เร็วกว่าแอพพลิเคชั่นบนเดสก์ท็อปที่ใช้ Java GUI
BobTurbo

3
ในฐานะนักพัฒนาเว็บฝั่งไคลเอ็นต์ที่จัดการกับ. webforms. net MVC, PHP, Rails, Django และหลากหลายทุกอย่าง แต่ Spring (ซึ่งฉันได้ยินมาดี) ใน Java ฉันคาดหวังว่าประสิทธิภาพ / สถาปัตยกรรมที่แย่ จากแบ็คเอนด์ที่สร้างโดยทีมจาวา ฉันสงสัยว่าปัญหาที่แท้จริงไม่ใช่มาตรฐาน แต่เป็นปัญหาของการมีเพียง Java อึเล็กน้อยจากที่นั่น นั่นไม่ใช่ความผิดของภาษา ไม่ใช่ความผิดของผู้พัฒนา Java ที่ฝึกฝนงานฝีมือและเรียนรู้ภาษาอื่นนอกเหนือจาก Java อย่างไรก็ตามอาจเป็นความผิดของ Sun, certs, '90s และอุตสาหกรรมไอทีโดยทั่วไป
Erik Reppen

คำตอบ:


236

Modern Java เป็นหนึ่งในภาษาที่เร็วที่สุดถึงแม้ว่ามันจะยังคงเป็นหมูหน่วยความจำ Java มีชื่อเสียงว่าเป็นคนช้าเพราะมันใช้เวลานานสำหรับ VM ในการเริ่มต้น

หากคุณยังคิดว่า Java ช้าให้ดูผลลัพธ์ของเกมมาตรฐาน รหัสที่ได้รับการปรับให้เหมาะสมที่สุดที่เขียนด้วยภาษาที่รวบรวมไว้ล่วงหน้า (C, Fortran และอื่น ๆ ) สามารถเอาชนะได้ อย่างไรก็ตามจาวาสามารถมากกว่า 10 เท่าเร็วเท่า PHP, Ruby, Python ฯลฯ มีพื้นที่เฉพาะที่สามารถเอาชนะภาษาคอมไพล์ทั่วไป (ถ้าพวกเขาใช้ห้องสมุดมาตรฐาน)

ไม่มีข้อแก้ตัวสำหรับแอปพลิเคชัน Java "ช้า" ในขณะนี้ นักพัฒนาและโค้ด / ไลบรารี่ดั้งเดิมต้องตำหนิมากกว่าภาษา นอกจากนี้ยังตำหนิ 'องค์กร' ด้วย

เพื่อความเป็นธรรมกับฝูงชน "Java ช้า" นี่คือพื้นที่ที่ยังคงช้า (อัปเดตสำหรับ 2013):

  • ไลบรารีมักเขียนขึ้นเพื่อ "ความถูกต้อง" และความสามารถในการอ่านไม่ใช่ประสิทธิภาพ ในความคิดของฉันนี่คือเหตุผลหลักที่ Java ยังมีชื่อเสียงไม่ดีโดยเฉพาะฝั่งเซิร์ฟเวอร์ สิ่งนี้ทำให้ปัญหาเกี่ยวกับสตริงแย่ลงอย่างมาก ข้อผิดพลาดทั่วไปบางอย่างเป็นเรื่องปกติ: วัตถุมักจะถูกใช้แทนการลดประสิทธิภาพและเพิ่มการใช้หน่วยความจำ ไลบรารี Java จำนวนมาก (รวมถึงไลบรารีมาตรฐาน) จะสร้าง Strings บ่อยครั้งแทนที่จะใช้รูปแบบที่ไม่แน่นอนหรือเรียบง่าย (char [] หรือ StringBuffer) สิ่งนี้ช้าและสร้างขยะจำนวนมากเพื่อรวบรวมในภายหลัง ในการแก้ไขปัญหานี้ฉันแนะนำให้นักพัฒนาใช้คอลเล็กชันดั้งเดิมและโดยเฉพาะห้องสมุดของ Javalution หากเป็นไปได้

  • การดำเนินการกับสตริงค่อนข้างช้า Java ใช้วัตถุสตริงที่เข้ารหัสไม่ได้UTF-16 ซึ่งหมายความว่าคุณต้องการหน่วยความจำเพิ่มขึ้นการเข้าถึงหน่วยความจำมากขึ้นและการดำเนินการบางอย่างมีความซับซ้อนมากกว่า ASCII (C, C ++) ในเวลานั้นเป็นการตัดสินใจที่ถูกต้องสำหรับการพกพา แต่มีค่าใช้จ่ายเล็กน้อย UTF-8ดูเหมือนจะเป็นตัวเลือกที่ดีกว่าตอนนี้

  • การเข้าถึง Array นั้นช้าลงเล็กน้อยเมื่อเทียบกับ Cเนื่องจากการตรวจสอบขอบเขต โทษนั้นใหญ่ แต่ตอนนี้เล็ก (Java 7 ปรับการตรวจสอบขอบเขตที่ซ้ำซ้อน)

  • การขาดการเข้าถึงหน่วยความจำโดยพลการสามารถทำให้ I / O และการประมวลผลระดับบิตช้าลง (เช่นการบีบอัด / คลายการบีบอัด) นี่เป็นคุณลักษณะด้านความปลอดภัยของภาษาระดับสูงส่วนใหญ่ในขณะนี้

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

  • I / O บนสตรีมนั้นช้าเนื่องจาก (IMO ตัวเลือกที่แย่) เพื่อต้องการการซิงโครไนซ์ในการเข้าถึงสตรีมแต่ละครั้ง NIOแก้ไขสิ่งนี้ แต่มันเจ็บปวดที่จะใช้ เราสามารถแก้ไขได้โดยการอ่าน / เขียนไปยังอาร์เรย์แทนที่จะเป็นองค์ประกอบในแต่ละครั้ง

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

  • เป็นเรื่องปกติที่จะเห็นแอปพลิเคชัน Java เชื่อมโยงกับ JVM เวอร์ชันเก่ามาก โดยเฉพาะฝั่งเซิร์ฟเวอร์ JVM เก่าเหล่านี้ไม่มีประสิทธิภาพอย่างไม่น่าเชื่อเมื่อเทียบกับรุ่นล่าสุด

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


อย่างไรก็ตามมีหลายที่ที่ Java เร็วกว่าภาษาอื่น ๆ :

  • การจัดสรรหน่วยความจำและการยกเลิกการจัดสรรนั้นรวดเร็วและประหยัด ฉันเห็นกรณีที่มันเร็วกว่า 20% (หรือมากกว่านั้น!) ในการจัดสรรอาร์เรย์ multi-kB ใหม่แทนที่จะใช้แคชที่นำมาใช้ใหม่

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

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

  • การซิงโครไนซ์และมัลติเธรดทำได้ง่ายและมีประสิทธิภาพ Java ได้รับการออกแบบให้มีความรู้ตั้งแต่เริ่มต้นและมันจะแสดง คอมพิวเตอร์สมัยใหม่มักจะมีหลายคอร์และเนื่องจากการสร้างเธรดเป็นภาษาคุณจึงสามารถใช้ประโยชน์ได้อย่างง่ายดาย โดยทั่วไปการเพิ่มความเร็ว 100% ถึง 300% เป็นพิเศษเมื่อเทียบกับรหัส C แบบเธรดเดี่ยว ใช่เธรด C ที่เขียนอย่างระมัดระวังและไลบรารีสามารถเอาชนะสิ่งนี้ได้ แต่นั่นเป็นงานพิเศษมากมายสำหรับโปรแกรมเมอร์

  • เงื่อนไขรวมถึงความยาว: การดำเนินการบางอย่างเร็วขึ้น การเต้นนี้จะใช้สตริงที่มีการคั่นด้วย null (ทั่วไปใน C) ใน Java 7, Oracle ได้ทำการเพิ่มประสิทธิภาพ String.subString () เพราะคนใช้มันอย่างโง่เขลาและได้รับการรั่วไหลของหน่วยความจำ

  • การทำสำเนาอาร์เรย์นั้นได้รับการปรับให้เหมาะสมที่สุด ในเวอร์ชันล่าสุด Java ใช้แอสเซมเบลอร์ที่ปรับด้วยมือสำหรับ System.arraycopy ผลลัพธ์คือในการดำเนินการ arraycopy / memcopy หนักฉันได้เห็นรหัสของฉันชนะเทียบเท่าใน C โดยอัตรากำไรที่เหมาะสม

  • คอมไพเลอร์ JIT เป็นสมาร์ทเกี่ยวกับการใช้L1 / L2แคช โปรแกรมที่รวบรวมไว้ล่วงหน้าไม่สามารถปรับแต่งโค้ดในแบบเรียลไทม์ไปยัง CPU และระบบเฉพาะที่กำลังทำงานอยู่ JIT ให้การแปลงลูปที่มีประสิทธิภาพมากด้วยวิธีนี้

ข้อเท็จจริงทางประวัติศาสตร์อีกสองสามประการที่ทำให้ชื่อเสียงของ "Java ช้า":

  • ก่อนการคอมไพล์ JIT (Java 1.2 / 1.3) ภาษานั้นถูกตีความเท่านั้นไม่คอมไพล์และช้ามาก
  • การรวบรวม JIT ต้องใช้เวลาเพื่อให้มีประสิทธิภาพ (การปรับปรุงที่สำคัญในแต่ละรุ่น)
  • Classloading มีประสิทธิภาพมากขึ้นกว่าปี มันค่อนข้างไม่มีประสิทธิภาพและช้าในช่วงเริ่มต้น
  • รหัสSwingและ UI ไม่ได้ใช้ฮาร์ดแวร์กราฟิกดั้งเดิมดีนัก
  • สวิงนั้นแย่มาก ฉันตำหนิ AWT และ Swing สำหรับสาเหตุที่ Java ไม่เคยสนใจเดสก์ท็อป
  • ใช้การซิงโครไนซ์อย่างหนักในคลาสไลบรารี รุ่นที่ไม่ซิงโครไนซ์พร้อมใช้งานแล้วในขณะนี้
  • แอปเปิ้ลใช้เวลาตลอดไปในการโหลดเนื่องจากการส่งJARแบบเต็มผ่านเครือข่ายและการโหลด VM เพื่อบูต
  • การซิงโครไนซ์ที่ใช้เพื่อดำเนินการลงโทษอย่างหนัก (ซึ่งได้รับการปรับให้เหมาะสมกับแต่ละ Java เวอร์ชัน) การสะท้อนกลับยังคงมีค่าใช้จ่ายสูง

49
Object instantiation and object-oriented features are blazing fast to use (faster than C++ in many cases) because they're designed in from the beginning.และCollections are fast. Standard Java beats standard C/C++ in this area, even for most optimized C code.ไม่ได้รับการสนับสนุนจากหลักฐานใด ๆ ที่เชื่อมโยงที่นี่
Sjoerd

8
@Sererd - การอ้างสิทธิ์นั้นไม่ค่อยดุร้าย - มันชัดเจนสำหรับฉันและควรเป็นกับทุกคนที่เข้าใจความแตกต่างในสถาปัตยกรรมของระบบหน่วยความจำเริ่มต้นใน C / C ++ เทียบกับ Java คุณสามารถทำได้ดีกว่านี้มากถ้าคุณเขียนตัวจัดการหน่วยความจำของคุณเอง (เช่นรายการฟรีพูลหน่วยความจำและอื่น ๆ ) หรือใช้ไลบรารีที่ใช้งานเช่นนั้น
Rex Kerr

15
@Rex Kerr - เหตุใดจึงต้องใช้ตัวจัดการหน่วยความจำหากคุณสามารถใช้เช่นสแต็กสำหรับการจัดสรร! คุณกำลังสับสนเกี่ยวกับการจัดสรรหน่วยความจำฮีปด้วยการสร้างอินสแตนซ์ของวัตถุ
Sjoerd

20
@Rex Kerr - โดยทั่วไปคุณอ้างว่าเนื่องจากทุกสิ่งใน Java เกี่ยวข้องกับการจัดสรรหน่วยความจำบนฮีปและเนื่องจากการจัดสรร Java บนฮีปใน Java นั้นเร็วกว่า C ++ ทุกอย่างใน Java จะเร็วกว่า นี่คือข่าวสำหรับคุณ: ใน C ++ คุณสามารถทำได้โดยไม่ต้องจัดสรรหน่วยความจำในฮีปในหลาย ๆ กรณี!
Sjoerd

10
@Sjoerd - ในกรณีที่ฉันบอกว่าทุกอย่างใน Java เร็วขึ้น? แค่อ่านสิ่งที่ฉันพูด ฉันพูดในสิ่งที่ฉันหมายถึงและพูดถึงทุกสิ่งที่คุณพูดในความคิดเห็นล่าสุดของคุณ
Rex Kerr

49

ตอนแรก Java นั้นไม่เร็วมาก แต่ก็ไม่ช้าเกินไปเช่นกัน วันนี้ Java เร็วมาก จากคนที่ฉันได้พูดคุยกับความประทับใจในการจาวาที่ช้านั้นมาจากสองสิ่ง:

  1. ช้าเวลาเริ่มต้น VM การนำ Java มาใช้ครั้งแรกใช้เวลานานในการเริ่มต้นและโหลดไลบรารีที่ต้องการและแอปพลิเคชันเทียบกับแอปพลิเคชันทั่วไป

  2. UI ช้า ต้นสวิงช้า มันอาจไม่ได้ช่วยให้ผู้ใช้ Windows ส่วนใหญ่พบว่าโลหะ L&F เริ่มต้นน่าเกลียดเช่นกัน

เมื่อกล่าวถึงข้างต้นก็ไม่น่าแปลกใจที่ผู้คนจะได้รับความประทับใจแบบ 'ชวาช้า'

สำหรับผู้ใช้หรือนักพัฒนาที่เคยพัฒนาแอพพลิเคชั่นพื้นฐานหรือแม้แต่แอพพลิเคชั่นVisual Basicจุดสองจุดนี้เป็นสิ่งที่มองเห็นได้มากที่สุดในแอพพลิเคชั่นและมันเป็นความประทับใจแรกที่คุณจะได้รับเกี่ยวกับแอพพลิเคชั่น กรณีเท่านั้น 1. ใช้.)

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

การทำลายความประทับใจแรกเป็นวิธีที่ดีในการเริ่มข่าวลือและตำนาน และข่าวลือและตำนานที่ยากจะฆ่า

ในระยะสั้น Java ไม่ช้า คนที่มี "Java เป็นทัศนคติที่ช้า" ขึ้นอยู่กับการแสดงผลครั้งแรกของ Java มากกว่า 10 ปีที่ผ่านมา


3
Java นั้นช้ามากเมื่อไม่กี่ปีที่ผ่านมา แต่ในการทดสอบเกณฑ์มาตรฐานเมื่อเร็ว ๆ นี้มันทำงานเกือบเร็วเท่ากับ C / C ++ และในบางสถานการณ์มันก็ทำงานได้เร็วขึ้น
ChadNC

23
แอพ Java บน OSX 10.6 บน Macbook ของฉันเริ่มช้ากว่าแอพที่เขียนใน Objective-C มีหลักฐานอะไรบ้างสำหรับเวลาเริ่มต้นที่รวดเร็ว
Zan Lynx

2
การบีบอัดไม่ใช่ปัญหาด้านประสิทธิภาพอย่างแน่นอน คอมพิวเตอร์ของฉันในปี 1992 คลายการบีบอัดไฟล์เมื่อเริ่มโปรแกรมที่ปรับปรุงประสิทธิภาพการโหลดไฟล์อีกต่อไปจากฮาร์ดไดรฟ์ ความแตกต่างระหว่าง CPU และฮาร์ดไดรฟ์เติบโตขึ้นอย่างมากในช่วงหลายปีที่ผ่านมา อย่างไรก็ตามมีปัญหากับการใช้รูปแบบไฟล์ zip สำหรับ rt.jar (ทำไม? !!!) และไฟล์คลาสที่บรรจุอยู่ไม่ได้ถูกเชื่อมโยง (ถั่ว !!)
Tom Hawtin - tackline

5
@Zan: โปรดทราบว่า Apple เขียน JVM สำหรับ Mac OS X (หรือดัดแปลงเป็นอย่างน้อย) Sun ได้ลงทุนค่อนข้างบางครั้งเพื่อให้เวลาเริ่มต้นเร็วขึ้นบนแพลตฟอร์มที่รองรับ (Windows, Linux และ Solaris) แต่พวกเขาไม่สามารถทำได้สำหรับ Mac OS x (เนื่องจากพวกเขาไม่ดูแลพอร์ตนั้น) อาจเป็นได้ว่า Mac ไม่สามารถ / ไม่ได้ใช้ / พอร์ตการเพิ่มประสิทธิภาพเหล่านั้นทั้งหมดกับ Mac OS X.
Joachim Sauer

1
ฉันไม่คิดว่าจาวาจะช้า (ฉันรู้จักผู้สร้างเกมที่สร้างเกมในพวกเขา); ไม่ดีสำหรับเหตุผล UI ไม่ใช่แอปพลิเคชัน java "ปกติ" ที่ฉันเคยเห็นมี UI ที่เหมาะสมและใช้งานได้ดี
RCIX

40

หลังจากอ่านหน้าเต็มไปด้วยความคิดเห็นที่บอกว่า Java ไม่ช้าฉันก็ต้องตอบด้วยความเห็นที่แตกต่าง

ความเชื่องช้าของภาษานั้นขึ้นอยู่กับความคาดหวังของคุณสำหรับ 'เร็ว' ถ้าคุณคิดว่า C # นั้นเร็ว Java ก็เร็วเหมือนกัน หากโดเมนปัญหาของคุณเกี่ยวข้องกับฐานข้อมูลหรือการประมวลผลแบบเรียลไทม์ Java ก็เร็วพอเช่นกัน หากคุณยินดีที่จะขยายแอปพลิเคชันของคุณโดยเพิ่มฮาร์ดแวร์เพิ่มเติม Java มีแนวโน้มที่จะรวดเร็วสำหรับคุณ หากคุณพิจารณาว่าการเร่งความเร็วของปัจจัยคงที่ในระดับ 5-10 นั้นไม่คุ้มค่าคุณอาจพิจารณาใช้ Java อย่างรวดเร็ว

หากคุณทำการคำนวณเชิงตัวเลขบนชุดข้อมูลขนาดใหญ่หรือถูกผูกไว้กับสภาพแวดล้อมการประมวลผลที่ทรัพยากร CPU ถูก จำกัด ซึ่งการเร่งความเร็วอย่างต่อเนื่องในระดับ 5-10 จะมีขนาดใหญ่ แม้การเพิ่มความเร็ว 0.5 อาจหมายถึงการลดลง 500 ชั่วโมงเพื่อให้การคำนวณเสร็จสมบูรณ์ ในกรณีเหล่านี้ Java ไม่อนุญาตให้คุณใช้สมรรถนะขั้นสุดท้ายและอาจพิจารณาว่า Java ช้า


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

33

คุณดูเหมือนจะถามคำถามที่แตกต่างกันสองคำถาม:

  1. Java ช้าจริงๆหรือไม่และถ้าเป็นเช่นนั้นทำไม
  2. ทำไม Java จึงรับรู้ช้าแม้ว่าจะเร็วกว่าทางเลือกอื่น ๆ

คำถามแรกคือคำถามที่ "มากแค่ไหน" มันมากับคำจำกัดความของคุณของ "ช้า" เมื่อเทียบกับล่ามล้วนๆ Java นั้นเร็วมาก เมื่อเทียบกับภาษาอื่น ๆ ที่ (ปกติ) เรียบเรียงบางส่วนของ bytecode แล้วรวบรวมแบบไดนามิกกับรหัสเครื่อง (เช่น C # หรือสิ่งอื่น ๆ บน. NET) Java เป็นคร่าว ๆ เมื่อเปรียบเทียบกับภาษาที่คอมไพล์เป็นรหัสเครื่องจริงและมีทีมงาน (มักใหญ่) ที่ทำงานโดยไม่ทำอะไรเลยนอกจากการปรับปรุงเครื่องมือเพิ่มประสิทธิภาพ (เช่น C, C ++, Fortran, Ada) Java ทำได้ค่อนข้างดีในบางสิ่ง แต่โดยรวม อย่างน้อยก็ค่อนข้างช้า

สิ่งนี้เกี่ยวข้องกับการติดตั้งเป็นหลัก - โดยพื้นฐานแล้วผู้ใช้กำลังรอในขณะที่คอมไพเลอร์แบบไดนามิก / JIT ทำงานดังนั้นถ้าคุณไม่มีโปรแกรมที่เริ่มทำงานมาระยะหนึ่งแล้ว ยากที่จะพิสูจน์ว่าการคอมไพเลอร์ใช้เวลากับการปรับแต่งที่ยากลำบาก ดังนั้นคอมไพเลอร์ Java (และ C # ฯลฯ ) ส่วนใหญ่จึงไม่ต้องใช้ความพยายามอย่างมากในการปรับแต่งที่ยากมาก ในหลายกรณีมีน้อยเกี่ยวกับการเพิ่มประสิทธิภาพที่จะเกิดขึ้น ปัญหาการปรับให้เหมาะสมหลายอย่างเสร็จสมบูรณ์แล้ว NP ดังนั้นเวลาที่พวกเขาเติบโตอย่างรวดเร็วด้วยขนาดของปัญหาที่ถูกโจมตี วิธีหนึ่งในการรักษาเวลาด้วยเหตุผลคือการใช้การปรับให้เหมาะสมกับสิ่งที่ต้องการฟังก์ชั่นครั้งเดียวเท่านั้น เมื่อเป็นเพียงนักพัฒนารอคอมไพเลอร์ คุณสามารถที่จะใช้เวลานานขึ้นและนำการเพิ่มประสิทธิภาพเดียวกันนั้นไปใช้กับชิ้นส่วนที่ใหญ่กว่าของโปรแกรม ในทำนองเดียวกันโค้ดสำหรับการปรับให้เหมาะสมบางอย่างจะมีขนสวย (และอาจใหญ่มาก) อีกครั้งเนื่องจากผู้ใช้กำลังรอในขณะที่โหลดรหัส (และเวลาเริ่มต้น JVM มักจะเป็นปัจจัยสำคัญในเวลาโดยรวม) การใช้งานจะต้องสมดุลเวลาที่บันทึกไว้ในที่เดียวกับที่หายไปในอีก - และให้รหัสน้อย ได้รับประโยชน์จากการปรับให้เหมาะสมแบบไร้ขนการทำให้ JVM มีขนาดเล็กมักเป็นประโยชน์มากกว่า

ปัญหาที่สองคือเมื่อใช้ Java คุณจะได้รับ "หนึ่งขนาดที่เหมาะกับการแก้ปัญหาทั้งหมด" บ่อยครั้ง ยกตัวอย่างเช่นสำหรับนักพัฒนา Java จำนวนมาก Swing เป็นห้องสมุดหน้าต่างเพียงอย่างเดียวที่มีอยู่ ในบางสิ่งบางอย่างเช่น C ++ นั้นมีไลบรารี windowing หลายสิบเฟรมเวิร์กแอพพลิเคชั่นและอื่น ๆ แต่ละชุดมีการประนีประนอมระหว่างความง่ายในการใช้งานกับการดำเนินการอย่างรวดเร็วรูปลักษณ์และความรู้สึกที่สอดคล้อง จุดยึดที่แท้จริงเพียงอย่างเดียวคือบางอย่าง (เช่น Qt) อาจมีราคาแพง (อย่างน้อยก็เพื่อการใช้งานเชิงพาณิชย์)

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

เพื่อสรุปการใช้งานปกติของ Java ทำให้ปัญหาการเพิ่มประสิทธิภาพสูงสุดที่ดีที่สุด ที่เลวร้ายยิ่งกว่าที่มองเห็น Java สิ่งต่าง ๆ เช่นชุดเครื่องมือหน้าต่างและเวลาเริ่มต้นของ JVM มักจะมีบทบาทที่ใหญ่กว่าความเร็วในการเรียกใช้ของภาษาเอง ในหลายกรณี C และ C ++ ยังได้รับเครดิตสำหรับสิ่งที่ผลิตภัณฑ์ของการเพิ่มประสิทธิภาพทำงานหนักขึ้นจริงๆ

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

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


16

มันเป็นข้อมูลที่ล้าสมัยจากวันแรก (กลางถึงปลายปี 1990) ของ Java Java ทุกเวอร์ชันที่สำคัญได้แนะนำการเพิ่มความเร็วอย่างมีนัยสำคัญเมื่อเทียบกับรุ่นก่อนหน้า เห็นได้ชัดว่าเมื่อรวม Oracle กับ JRockit กับ JVM สำหรับ Java 7 ของซันแนวโน้มนี้ดูเหมือนจะดำเนินต่อไป

เปรียบเทียบกับภาษาสมัยใหม่อื่น ๆ ที่เป็นที่นิยม (Python, Ruby, PHP), Java เป็นจริงเร็วกว่าสำหรับการใช้งานมากที่สุด มันไม่ค่อยตรงกับ C หรือ C ++ แต่สำหรับหลาย ๆ งานมันใกล้พอ ความกังวลเกี่ยวกับประสิทธิภาพที่แท้จริงควรจะเกี่ยวกับจำนวนหน่วยความจำที่ใช้


14

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

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

ใน Java การเชื่อมโยงเกิดขึ้นทุกครั้งที่มีการเรียกใช้แอปพลิเคชัน ดังนั้นเวลาเริ่มต้นที่ยาวนาน

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

สำหรับประสิทธิภาพหลังจากนั้นมาตรฐานของฉันเองในการคำนวณขนาดเล็กที่มีการเข้าถึงอาร์เรย์ (ส่วนใหญ่ฟังก์ชั่นแฮชและอัลกอริทึมการเข้ารหัสลับอื่น ๆ ) มักจะแสดงให้เห็นว่ารหัส C ที่เหมาะสมที่สุดนั้นเร็วกว่าโค้ด Java ประมาณ 3 เท่า บางครั้ง C เร็วกว่า Java เพียง 30% และบางครั้ง C ก็เร็วกว่า 4x ขึ้นอยู่กับอัลกอริทึมที่นำไปใช้งาน ผมเห็นเป็นปัจจัย 10x เมื่อ "C" รหัสเป็นจริงประกอบเลขคณิตจำนวนเต็มใหญ่เนื่องจากการ 64x64-> 128 คูณ opcodes ว่าข้อเสนอการประมวลผล แต่ Java ไม่สามารถใช้เพราะชนิดจำนวนเต็มยาวที่สุดของมันคือ long64 นี่คือกรณีขอบ ภายใต้เงื่อนไขที่ปฏิบัติ I / O และแบนด์วิดธ์หน่วยความจำการพิจารณาป้องกันรหัส C จากการถูกจริงๆสามครั้งเร็วกว่า Java


อืม ... ฉันคิดว่าไลบรารี C ส่วนใหญ่เชื่อมโยงกันแบบไดนามิกทุกวันนี้ด้วย หรือคุณกำลังพูดถึงสิ่งที่แตกต่างกันอย่างไร
Sean McMillan

4
@Sean: การเชื่อมโยงแบบไดนามิกสำหรับ C เกิดขึ้นสำหรับ "สัญลักษณ์ภายนอก": ฟังก์ชั่นที่ใช้ใน DLL หนึ่งและกำหนดไว้ในอีก แอปพลิเคชัน C ทั่วไปจะใช้ DLL โหล สำหรับการลิงก์ Java แบบไดนามิกเกิดขึ้นสำหรับวิธีการทั้งหมดในทุกคลาส: มีหลายพันรายการในแอปพลิเคชัน Java ทั่วไป (รวมถึงไลบรารีมาตรฐาน) ในโลก C การเชื่อมโยงส่วนใหญ่ (การเชื่อมโยงทั้งหมดที่ไม่ข้ามขอบเขต DLL) ได้รับการแก้ไขในเวลารวบรวมเพียงส่วนเล็ก ๆ ที่ยังคงต้องทำในขณะทำงาน
โทมัสพริน

14

Java ช้าอย่างแน่นอนโดยเฉพาะงานเชิงปริมาณ

ฉันใช้การผสมผสานของR , Python และ C / C ++ กับไลบรารีATLASแบบมัลติเธรดที่ปรับให้เหมาะสม ในแต่ละภาษาเหล่านี้ฉันสามารถเมทริกซ์คูณเมทริกซ์ 3000 คูณ 3000 ด้วยตัวมันเองภายใน 4 วินาที ใช้ Colt และ Parallel Colt ใน Java การดำเนินการเดียวกันใช้เวลา 185 วินาที! พิศวงถึงแม้ไลบรารี java เหล่านี้จะขนานกันตามธรรมชาติ

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

เครื่องของฉันคือ HP Core 2 Duoพร้อม RAM ขนาด 3 GB ฉันใช้Ubuntu 10.04 64 บิต(Lucid Lynx)


จากความคิดเห็นข้างต้นของฉันฉันดำเนินการคูณเมทริกซ์เดียวกันโดยใช้ JAMA และใช้เวลาประมาณ 50 วินาที ยังช้าเกินไปเมื่อเทียบกับภาษาอื่น
Hamaad Shah

7
Java ใช้เวลานานแค่ไหนเมื่อคุณทำการคูณใน libraires ที่เรียกผ่าน JNI เนื่องจากทุกสิ่งที่คุณสามารถทำได้ใน C / C ++ คุณสามารถทำกับ JNI (เพิ่มไม่กี่ร้อย mnano-วินาที) ระยะขอบนั้นค่อนข้างเล็ก ฉันเดาว่าการคูณเมทริกซ์ R และ Python ของคุณไม่ได้เขียนใน R หรือ Python เพียงแค่เรียกจากภาษาเหล่านั้น
Peter Lawrey

2
จากความอยากรู้อยากเห็นคุณเคยทำโปรไฟล์เพื่อระบุว่าคุณมีฮอตสปอตในรหัสของคุณหรือไม่
Thorbjørn Ravn Andersen

10

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

มันไม่ได้ช่วยให้เวลาในการหมุนของ JVM ช้าลงและการดาวน์โหลดแอปเพล็ตนั้นถูกสร้างด้วยผงกาแฟ Java อย่างชัดเจน เมื่อFlashใช้เวลาในการโหลดนาน ๆ แบรนด์ของข้อความ "กำลังโหลด" จะถูกระบุโดยผู้พัฒนา Flash ดังนั้นผู้คนจึงไม่โทษเทคโนโลยีแฟลชโดยรวม

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


9

Java มีชื่อเสียงของการช้าเพราะมันก็ช้า Java เวอร์ชันแรกมีการรวบรวม Just In Time ไม่มากหรือน้อย นี่หมายความว่ารหัสถึงแม้ว่า bytecode กำลังถูกตีความดังนั้นแม้แต่การดำเนินการที่ง่ายที่สุด (เช่นการเพิ่มจำนวนเต็มสองจำนวน) เครื่องก็ต้องทำการเปรียบเทียบทั้งหมดและเปรียบเทียบตัวชี้และฟังก์ชั่นการโทร คอมไพเลอร์ JIT ได้รับการปรับปรุงอย่างต่อเนื่อง ตอนนี้เป็นจุดที่ถ้าฉันเขียนรหัส C ++ อย่างไม่ระมัดระวังและโค้ด Java อย่างไม่ระมัดระวังบางครั้ง Java จะมีประสิทธิภาพสูงกว่า C ++ เพราะคอมไพเลอร์ JIT ตระหนักว่าฉันมีตัวชี้ที่ไม่จำเป็นบางอย่างที่ไม่จำเป็นและจะดูแลมันสำหรับฉัน

หากคุณต้องการที่จะเห็นเพียงวิธีการใหญ่ความแตกต่าง JIT รวบรวมรถตรวจสอบเทียบกับมาตรฐานที่ไม่ใช่ตีความตีความที่เกณฑ์มาตรฐานเกมคอมพิวเตอร์ภาษา (Pidigits ใช้ไลบรารีภายนอกเพื่อทำการคำนวณทั้งหมดดังนั้นเบนช์มาร์กจึงไม่เปลี่ยนแปลงส่วนอื่น ๆ แสดงความเร็ว 6-16x!)

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


6

Java WAS ช้ากลับมาในวันนี้ มันได้กลายเป็นเร็วขึ้นมากเนื่องจากกี่รุ่นของการปรับปรุงประสิทธิภาพการทำงาน ครั้งล่าสุดที่ฉันได้ยินมันมักจะอยู่ภายใน 10% ของความเร็ว C # - บางครั้งเร็วกว่าบางครั้งช้ากว่า

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

นอกจากนี้ยังมีอย่างน้อยบางคนที่จะไม่เชื่อในความมีชีวิตของ Java


1
การเริ่มต้น JVM ยังช้ากว่าการเริ่ม CLR มาก นี่เป็นเพราะซันลากเท้าในวิธีที่แย่ที่สุดในการปล่อย Java 7 ดังนั้นเราจึงติดอยู่กับ patch ที่เพิ่มขึ้นในJava 6 อายุ 4 ปี
BobMcGee

3
ว้าว Java 6 อายุ 4 ปี ??? ใช่ฉันเดาเช่นนั้น (ถ้าคุณนับเบต้า) ยังคงรู้สึกใหม่สำหรับฉัน - ฉันเพิ่งหยุดใช้ 1.4 ที่ทำงาน
Kaleb Brasee

Java 1.4 นั้นสามารถใช้งานได้ แต่เป็น sucktastic ชนิดหนึ่งตั้งแต่ 1.5 และ 1.6 เพิ่มประสิทธิภาพและน้ำตาล syntactic ขอบเขต - ตรวจสอบและเพิ่มประสิทธิภาพ System.arraycopy ถูกนำมาใช้ตั้งแต่นั้น ดังนั้นการปรับปรุงการซิงโครไนซ์เป็นจำนวนมาก ฉันคิดว่ามันยุติธรรมที่จะบอกว่า 1.4 ช้าจริง ๆ
BobMcGee

ฮ่า ๆ ฉันรู้ - ทุกครั้งที่ฉันต้องทำซ้ำด้วยตนเองหรือใช้อาร์เรย์แทนรายการทั่วไปฉันต้องการทำลายแล็ปท็อปของฉันครึ่ง ... IBM ได้จริง Java 5 มีอยู่บน WAS 6.1 เป็นเวลาหลายปี แต่ฉัน ' ฉันติดอยู่บน WAS 6.0 :( ฉันใช้ Java 5/6 มาแล้วเพราะมันเป็นของตัวเอง แต่ถูก จำกัด โดยรุ่นเซิร์ฟเวอร์เก่าที่ทำงานมีการปรับปรุงประสิทธิภาพการทำงานเป็นสองเปอร์เซ็นต์จาก 1.4 เป็นเวอร์ชั่นใหม่ล่าสุด สำหรับหลายสิ่งหลายอย่างและฉันตั้งตารอคอยพวกเขา
Kaleb Brasee

6

สเตฟาโน:

ฉันได้อยู่กับ Java มาตั้งแต่ต้นดังนั้นจากมุมมองของฉันชื่อเสียงของความช้าถูกสร้างขึ้นโดยส่วนหน้า GUI ที่ไม่ตอบสนองและช้า (AWT และจากนั้นแกว่ง) และใน Applets อาจเป็นเพราะเวลาเริ่มต้นช้าเพิ่มเติมของ VM ของ

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

Java ที่แบ็กเอนด์และระดับการคำนวณนั้นไม่ช้า ค้นเป็นหนึ่งในตัวอย่างที่ดีที่สุด:

การปล่อยโคลต์ที่เสถียรล่าสุดจะแบ่งสิ่งกีดขวาง 1.9 Gflop / s บน JDK ibm-1.4.1, RedHat 9.0, 2x IntelXeon@2.8 GHz

มีหลายสิ่งที่นอกเหนือจาก Java หลัก ๆ ที่ควรได้รับการพิจารณาเช่น Realtime Java หรือกลไกพิเศษเพื่อเพิ่มความเร็วเช่นJavolutionเช่นเดียวกับการรวบรวม Ahead-Of-Time (เช่น gcj) นอกจากนี้ยังมี IC เป็นเรื่องที่สามารถดำเนินการ Java Bytecode โดยตรงอย่างเช่นคนที่อยู่ในปัจจุบันและ iPhones iPods ARM Jazelle

ฉันคิดว่าโดยทั่วไปในวันนี้เป็นการตัดสินใจทางการเมือง (เช่นไม่มีการสนับสนุน Java บน iPhone / iPod) และการตัดสินใจกับ Java เป็นภาษา (เพราะหลายคนคิดว่ามันเกินไป)

อย่างไรก็ตามมีภาษาอื่น ๆ อีกมากมายสำหรับ Java VM ในปัจจุบัน (เช่น Python, Ruby, JavaScript, Groovy, Scala ฯลฯ ) ซึ่งอาจเป็นทางเลือกอื่น

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


ตกลงดังนั้นชื่อเสียงที่ไม่ดีอื่นมาจากชุดเครื่องมือ GUI แน่นอนฉันคิดว่าเนื่องจาก JVM สมัยใหม่ใช้วิดเจ็ตเนทิฟมันจึงเชื่อมต่อเข้ากับไลบรารี่ OS ได้ใช่ไหม หรือพวกเขาใช้ AWT / Swing เพื่อสร้างรูปลักษณ์และความรู้สึกเดียวกันกับแพลตฟอร์มโฮสต์
Stefano Borini

สเตฟาโน: วงสวิงขึ้นอยู่กับแนวคิดของการแสดงผลวิดเจ็ตสากลที่ไม่ใช่เจ้าของภาษาดังนั้นสมมติฐานของคุณจึงผิด เป็นกลไก "รูปลักษณ์และความรู้สึกที่เสียบปลั๊กได้" ที่ช่วยให้ส่วนประกอบของ Swing สามารถเลียนแบบลักษณะของส่วนประกอบดั้งเดิมได้ หากคุณกำลังมองหาบางอย่างเช่นนั้นคุณอาจต้องการตรวจสอบ SWT ( eclipse.org/swt ) ซึ่งจะเชื่อมต่อกับระบบปฏิบัติการดั้งเดิมและใช้วิดเจ็ตดั้งเดิมโดยใช้ JNI (ซึ่งกล่าวกันว่าเป็นคอขวด)
Dieter

Java2D (ใช้สำหรับ Swing) เป็นสิ่งที่รวดเร็วมากในวันนี้และการใช้ native widgets (SWT) ไม่ได้ให้ประโยชน์ด้านประสิทธิภาพเลย อย่างน้อยนั่นคือสิ่งที่ฉันอ่านเมื่อฉันตัดสินใจว่าจะเรียนรู้การสวิงหรือ SWT 6 เดือนที่ผ่านมา
Luigi Plinge

4

ค้อนช้ากว่าการรีดแป้งมากกว่าเครื่องมืออื่น ๆ ไม่ทำให้ค้อน "ช้าลง" หรือมีประโยชน์น้อยกว่าสำหรับงานที่ออกแบบมาให้ทำ

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

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


3

Java เป็นภาษาระดับสูงและชื่อเสียงในปัจจุบันคือการมีประสิทธิภาพเทียบเท่ากับภาษาระดับสูงอื่น ๆ ที่เทียบเท่า

  1. มันมีความหมายผูกพันแบบไดนามิก เมื่อเทียบกับ C ++ ที่มีการรวบรวมวิธีที่ไม่ใช่เสมือนเป็นการเรียกใช้ฟังก์ชันแม้แต่คอมไพเลอร์ Java ที่ดีที่สุดในโลกก็ต้องสร้างโค้ดที่มีประสิทธิภาพน้อยกว่า แต่มันก็เป็นความหมายที่สะอาดและมีระดับสูงขึ้น

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

  3. วิธีที่ Java เป็นภาษาระดับสูงก็คือโดยมีขยะเก็บ การรวบรวมขยะอาจช้ากว่าmallocและfreeสำหรับโปรแกรมที่จัดสรรทันทีหน่วยความจำทั้งหมดที่พวกเขาต้องการและทำงานด้วย ปัญหาคือในภาษาที่ไม่ได้มีการเก็บขยะโปรแกรมเมอร์มักจะเขียนเพียงโปรแกรมที่จัดสรรหน่วยความจำทั้งหมดที่พวกเขาต้องการในครั้งเดียวและล้มเหลวถ้ามันจะเปิดออกบางส่วนคงที่ขนาดสูงสุดโดยพลการได้รับ overflown ดังนั้นการเปรียบเทียบคือแอปเปิ้ลกับส้ม เมื่อโปรแกรมเมอร์พยายามเขียนและดีบักโปรแกรมด้วยการจัดสรรแบบไดนามิกของโครงสร้างที่ถูกล่ามโซ่ในภาษาที่ไม่ใช่ GC บางครั้งพวกเขาพบว่าโปรแกรมของพวกเขาไม่เร็วกว่าในภาษา GC เพราะmallocและfreeไม่ฟรี! พวกเขามีค่าใช้จ่ายเกินไป ... อีกทั้งไม่มีกองกำลัง GC เพื่อระบุว่าใครเป็นอิสระและต้องระบุว่าใครจะปลดปล่อยอะไรบ้างในบางครั้งบังคับให้คุณทำสำเนา - เมื่อฟังก์ชั่นหลายอย่างต้องการข้อมูลและไม่ชัดเจนว่า จะใช้งานครั้งสุดท้ายในขณะที่การคัดลอกไม่จำเป็นในภาษา GC


1. อาจไม่เป็นจริงด้วย HotSpot 2. เฉพาะเมื่อคุณทำเครื่องหมายวิธีเป็นการซิงโครไนซ์
Winston Ewert

1
1. คอมไพเลอร์ไม่ปรับรหัสให้เหมาะสม แต่ JVM นั้นฉลาดพอที่จะกำหนดวิธีการเสมือนได้เพียงหนึ่งหรือสองวิธีเท่านั้นและสามารถเรียกได้ว่าเป็นแบบคงที่หรือแม้กระทั่งในบรรทัด ฉันค่อนข้างมั่นใจว่า C ++ ไม่สามารถใช้วิธีเสมือนแบบอินไลน์ 2. Java Object ทุกอันจะมีการล็อค มันมีค่าใช้จ่ายเล็ก ๆ (ประมาณหนึ่งไบต์) ในแต่ละวัตถุ แต่มีผลกระทบเล็กน้อยหากไม่ได้ใช้ 3. ใน Java คุณสามารถจัดสรร Object ทั้งหมดที่คุณต้องการได้ในคราวเดียว สามารถให้แอปพลิเคชั่นที่ไม่ใช่ GC ได้ทั้งวัน ;) GC ของ Java นั้นมีหลายเธรดโดยปริยายสิ่งที่ต้องใช้ libraires พิเศษใน C ++
Peter Lawrey

C ++ สามารถอินไลน์การโทรเสมือน แต่ Java สามารถทำได้ในหลายกรณีและยังแข็งแกร่งขึ้นด้วยการเพิ่มประสิทธิภาพไซต์โทร megamorphic
Piotr Kołaczkowski

2

ในช่วงกลางยุคเมื่อ Java เข้าสู่กระแสหลัก C ++ เป็นภาษาที่โดดเด่นและเว็บก็ยังใหม่อยู่ นอกจากนี้ JVMs และ GC เป็นแนวคิดที่ค่อนข้างใหม่ในการพัฒนากระแสหลัก JVMs ยุคแรกนั้นค่อนข้างช้า (เมื่อเทียบกับ C ++ ที่รันบนโลหะเปลือย) และยังได้รับความทุกข์ทรมานจากการหยุดการรวบรวมขยะในบางครั้งซึ่งทำให้ชื่อเสียงของ Java ช้าลง


เป็นเพราะเทคโนโลยีที่อยู่เบื้องหลัง GC หรือไม่ ฉันรู้ว่าพวกเขามีกลยุทธ์บางอย่าง (เช่นเลเยอร์ generational สำหรับวัตถุ) จะมีประสิทธิภาพมากขึ้นในระยะ GC กลยุทธ์ในเวลานั้นคืออะไร?
Stefano Borini

1
ผู้เชี่ยวชาญของ IANA JVM แต่ฉันคิดว่าในเวลานั้นมีอัลกอริธึมการทำเครื่องหมาย / การกวาดแบบเธรดเดียวที่ใช้สำหรับ GC ซึ่งต้องการให้ทั้ง JVM หยุดชั่วคราวในขณะที่ GC กำลังทำงานอยู่ ทุกวันนี้มีเครื่องหมาย / การกวาดพร้อมกันและยังมีการปรับปรุงประสิทธิภาพอื่น ๆ อีกมากมายใน JVM
เคนหลิว

2
อัลกอริทึม GC สมัยใหม่นั้นดี แต่ฉันคิดว่าการปรับปรุงที่ยิ่งใหญ่ที่สุดคือ JIT
Pascal Thivent

1

แอปเดสก์ท็อป Java จำนวนมาก (เวลา: สิ่งที่คล้าย Eclipse) มีการตอบสนอง GUI ที่ไม่ดีอาจเกิดจากการใช้หน่วยความจำสูงและความจริงที่ว่า classloader สามารถทำ IO ได้มากมาย มันพัฒนาขึ้น แต่ก็แย่ลงเมื่อไม่กี่ปีที่ผ่านมา

คนส่วนใหญ่ชอบทำภาพรวมดังนั้นพวกเขาจึงพูดว่า "Java ช้า" เพราะพวกเขาเห็นว่าแอพนั้นช้าเมื่อพวกเขาโต้ตอบกับพวกเขา


คุณคิดว่าปริมาณการใช้หน่วยความจำสูงมาจากเครื่องมือหรือจากไลบรารี java?
Stefano Borini

ในกรณีของ Eclipse - จากโครงสร้างพื้นฐาน Eclipse นั้นเอง เช่นเดียวกับ GUI "หนัก" ในอดีต (JBuilder ที่ฉันจำได้) ฉันมีความรู้สึกว่าเป็นเพราะวัตถุจำนวนมากต้องใช้สถาปัตยกรรมปลั๊กอิน (เช่น Eclipse) ในภาษาที่พิมพ์แบบคงที่ Emacs มีปลั๊กอินเช่นกันและใช้หน่วยความจำน้อยกว่า Eclipse 10-20x เมื่อทำการเข้ารหัสทั่วไป รหัส Emacs Lisp ถูกคอมไพล์ไปเป็น bytecode และโหลดลงในอินสแตนซ์ของ emacs จากนั้นเรียกใช้ - คล้ายกับ Java classloader ฉันเดาว่าใน Java มีอ็อบเจกต์ระดับกลางมากมายที่ถูกทำให้เป็นอินสแตนซ์เพื่อให้สามารถใช้งานได้บางอย่าง
Wojciech Kaczmarek

1

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

เหตุผลที่ Sun JVM มีขนาดใหญ่ก็เพราะว่ามันมีล่ามรหัสไบต์ที่ดีมากซึ่งทำงานได้โดยการติดตามสิ่งต่างๆมากมาย นั่นหมายถึงข้อมูลจำนวนมากซึ่งหมายถึงหน่วยความจำ

คุณอาจต้องการดูเครื่องเสมือน jamvm ซึ่งเป็นล่ามที่รวดเร็วพอสมควร (ไม่มีรหัสภาษา) และมีขนาดเล็กมาก มันเริ่มต้นขึ้นอย่างรวดเร็ว


1

Pascal กล่าวว่า Java เป็นภาษาที่เทียบเท่ากับภาษาระดับสูงอื่น ๆ อย่างไรก็ตามในฐานะที่เป็นคนที่ทำงานกับ JVM ดั้งเดิมบนWindows 98ในขณะที่ระดับของ abstraction ที่จัดทำโดยเครื่องเสมือน Java คือเราจะพูดว่าเจ็บปวด

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


0

ผู้คนมักจะวิ่งเหยาะๆเส้น "มันตีความ" เพราะกาลครั้งหนึ่งนานมาแล้วการกดที่ไม่ดีทำให้ผู้ที่ทิ้ง Java ว่า 'ช้าเกินไป' และไม่เคยกลับไปทดสอบเวอร์ชันที่ใหม่กว่า

หรือบางที "คนโง่" เป็นคำตอบที่ดีกว่า


0

ฉันคิดว่าสักวันอาจจะไม่ได้ในอนาคตอันใกล้ภาษาที่คอมไพล์ด้วย JIT จะมีประสิทธิภาพสูงกว่าภาษาที่คอมไพล์ในด้านใด ๆ (อาจไม่ใช่เวลาเริ่มต้น / การใช้หน่วยความจำ) เนื่องจากความจริงที่ว่าคอมไพเลอร์ JIT พฤติกรรมและแพลตฟอร์มที่พวกเขากำลังทำงานอยู่


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

ขอบคุณสำหรับคำตอบไม่เคยคิดเลยว่าคอมไพเลอร์ของ JIT จะมีเวลาน้อย
helpermethod

คุณหมายถึงอะไรเช่นการเพิ่มประสิทธิภาพการปรับตัวของฮอตสปอต?
Stefano Borini

2
@BobMcGee: ถูกต้องมาก สามารถสร้างโปรแกรม C ++ เพื่อให้ทำงานช้าลงพร้อมกับแสดงความคิดเห็นโปรไฟล์สำหรับการดำเนินการทั้งหมด คอมไพเลอร์มีอิสระในการสร้างเวอร์ชันที่รวดเร็วมากโดยใช้เวลาครึ่งชั่วโมงของ CPU และ RAM 2 GB JIT ที่ทำสิ่งนี้จะทำให้ผู้ใช้ออกไป
Zan Lynx

1
เวลารวบรวมของ JIT นั้นเล็กน้อยสำหรับแอปที่ใช้งานนานเช่นเซิร์ฟเวอร์ AOT กับ PGO นั้นมีข้อ จำกัด มากกว่าเมื่อเปรียบเทียบกับ JIT อย่างน้อย 2 เหตุผล ประการแรกความแตกต่างด้านประสิทธิภาพส่วนใหญ่ทำได้ด้วยการปรับน้ำหนักเบาให้เหมาะสมที่สุด เปรียบเทียบ gcc -O2 กับ gcc -O3 เวลาส่วนใหญ่ไม่มีความแตกต่างบางครั้ง -O3 อาจดีขึ้นเล็กน้อยบางครั้งก็แย่ลงเล็กน้อย แต่ฉันไม่เคยพบความแตกต่างจาก 2x นี้ ประการที่สองการใช้ AOT แม้กับ PGO คุณสามารถเดาได้ว่าโปรไฟล์จะอยู่ที่การใช้งานไซต์ เดาผิดและคุณอยู่ไกลจาก JIT และโปรไฟล์จริงสามารถขึ้นกับการกำหนดค่าได้อย่างมาก
Piotr Kołaczkowski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.