scala vs java, ประสิทธิภาพและหน่วยความจำ? [ปิด]


160

ฉันกระตือรือร้นที่จะดู Scala และมีคำถามพื้นฐานที่ฉันไม่สามารถหาคำตอบ: โดยทั่วไปมีประสิทธิภาพและการใช้หน่วยความจำระหว่าง Scala และ Java แตกต่างกันหรือไม่


3
ฉันเคยได้ยินว่าการแสดงนั้นใกล้เคียงกันมาก ฉันสงสัยว่ามันขึ้นอยู่กับว่าคุณกำลังทำอะไร (เช่นเดียวกับ Java vs C)
Peter Lawrey

คำตอบสำหรับทุกประเภทของคำถามเหล่านี้คือ "มันขึ้นอยู่กับ" - สำหรับแทบเปรียบเทียบระบบ X VS ระบบวายพลัสใด ๆ นี้ซ้ำstackoverflow.com/questions/2479819/...
เจมส์มัวร์

คำตอบ:


261

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

int n = 0;
for (String s: array) {
  if (s.length > 2 && mapping.containsKey(s)) n++;
}
String[] bigEnough = new String[n];
n = 0;
for (String s: array) {
  if (s.length <= 2) continue;
  bigEnough[n++] = map.get(s);
}

ต๊าย! การทำงานอย่างหนัก. ใน Scala วิธีที่กะทัดรัดที่สุดในการทำสิ่งเดียวกันคือ:

val bigEnough = array.filter(_.length > 2).flatMap(mapping.get)

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

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

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

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


172
+1 สำหรับย่อหน้าสุดท้าย มันเป็นจุดสำคัญที่ปล่อยออกมาจากการพิจารณาไกลบ่อยเกินไป
เควินไรท์

2
ฉันคิดว่ามุมมองจะช่วยได้มากกับปัญหาที่คุณพูดถึง หรือไม่จริงกับอาร์เรย์โดยเฉพาะ?
Nicolas Payette

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

1
>> ในสไตล์ที่มีประสิทธิภาพสูง << มีที่ว่างในเกมมาตรฐานสำหรับโปรแกรมสำนวนที่ไม่ประสบความสำเร็จ "ยอดเยี่ยม"
igouy

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

103

ฉันเป็นผู้ใช้ใหม่ดังนั้นฉันไม่สามารถเพิ่มความคิดเห็นในคำตอบของ Rex Kerr ด้านบน (การอนุญาตให้ผู้ใช้ใหม่เพื่อ "ตอบ" แต่ไม่ใช่ "ความคิดเห็น" เป็นกฎที่แปลกมาก btw)

ฉันลงทะเบียนเพื่อตอบสนองต่อ "phew, Java นั้นละเอียดมากและการทำงานหนักมาก" ของคำตอบที่ได้รับความนิยมของ Rex ด้านบน ในขณะที่คุณสามารถเขียนโค้ดสกาล่าที่รัดกุมกว่านี้ได้ตัวอย่าง Java ที่ให้นั้นมีความชัดเจน นักพัฒนา Java ส่วนใหญ่จะเขียนโค้ดดังนี้:

List<String> bigEnough = new ArrayList<String>();
for(String s : array) {
  if(s.length() > 2 && mapping.get(s) != null) {
    bigEnough.add(mapping.get(s));
  }
}

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

List b=new ArrayList();
for(String s:array)
  if(s.length()>2 && mapping.get(s) != null) b.add(mapping.get(s));

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


7
ทำไมคุณไม่ได้เป็นสมาชิกของชมรม "ภาษาฮิปของเดือน"? ความคิดเห็นที่ดี ฉันชอบอ่านย่อหน้าสุดท้ายเป็นพิเศษ
stepanian

21
ใส่อย่างดีเลิศ! ฉันเริ่มเบื่อกับตัวอย่างที่ถูกประดิษฐ์โดยโค้ด Java ที่สูงเกินจริงตามมาด้วยตัวอย่างที่สร้างขึ้นอย่างรอบคอบตัวอย่างสั้น ๆ ของ Scala (หรือภาษา FP อื่น ๆ ) และจากนั้นข้อสรุปที่ดึงมาอย่างฉับพลันว่า Scala จะต้องดีกว่า Java เพราะ ใครเคยเขียนอะไรที่มีความสำคัญใน Scala อยู่ดี! ;-) และอย่าพูดว่า Twitter ...
chrisjleu

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

5
ในขณะที่เราอยู่ใน java8 มันจะเป็น:Arrays.stream(array).map(mapping::get).filter(x->x!=null).toArray(File[]::new);
bennyl

2
สิ่งที่ทำให้ Scala "ดีกว่า" ในบางแง่มุมกว่า Java คือความสามารถของระบบประเภทที่ขยายเพิ่มขึ้นซึ่งทำให้ง่ายต่อการแสดงรูปแบบทั่วไปมากขึ้นเช่นประเภท (เช่น Monads, Functors เป็นต้น) สิ่งนี้ช่วยให้คุณสร้างประเภทที่ไม่ได้มาเนื่องจากสัญญาที่เข้มงวดมากเกินไปซึ่งมักเกิดขึ้นใน Java สัญญาที่เข้มงวดไม่ได้ขึ้นอยู่กับรูปแบบที่เกิดขึ้นจริงในรหัสเป็นเหตุผลรูปแบบการกลับมาของความรับผิดชอบมีความจำเป็นเพียงเพื่อทดสอบหน่วยของคุณอย่างถูกต้อง (พึ่งพาการฉีดขึ้นอยู่กับใจก่อนและ XML Hell จะนำมา) ส่วนเสริม ความกระชับทำให้เกิดความยืดหยุ่นเป็นเพียงโบนัส
josiah

67

เขียน Scala ของคุณเช่น Java และคุณสามารถคาดหวังว่ารหัสไบต์เดียวกันเกือบจะถูกปล่อยออกมา - ด้วยตัวชี้วัดที่เกือบเหมือนกัน

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

นอกจากนี้มูลค่าการกล่าวถึงก็คือความจริงที่ว่าหน่วยความจำเพิ่มเติม / ความเร็วที่น้อยลงเป็นการหลีกเลี่ยงไม่ได้เมื่อเขียนโค้ดที่สามารถทำงานแบบขนานได้ รหัส Idiomatic Scala นั้นมีความเป็นธรรมชาติมากกว่ารหัส Java ทั่วไปและมักจะเป็นเพียง 4 ตัวอักษร ( .par) ห่างจากการขนานกันหมด

ดังนั้นถ้า

  • โค้ดสกาล่าใช้เวลานานกว่าโค้ด Java 1.25 เท่าในเธรดเดี่ยว
  • สามารถแบ่งได้อย่างง่ายดายใน 4 คอร์
  • สำหรับเวลารันแบบขนานของ (1.24 / 4 =) 0.3125x ของ Java ดั้งเดิม

คุณจะบอกว่าตอนนี้โค้ดสกาล่านั้นค่อนข้างช้ากว่า 25% หรือเร็วกว่านี้อีกประมาณ 3 เท่า?

คำตอบที่ถูกต้องขึ้นอยู่กับวิธีที่คุณกำหนด "ประสิทธิภาพ" :)


4
อนึ่งคุณอาจต้องการพูดถึงที่.parอยู่ใน 2.9
Rex Kerr

26
>> จากนั้นคุณจะบอกว่าตอนนี้โค้ดสกาล่านั้นค่อนข้างช้ากว่า 25% หรือเร็วกว่าเดิมถึง 3 เท่า? << ผมว่าทำไมคุณไม่เปรียบเทียบสมมุติฐานกับโค้ด Java แบบมัลติเธรด?
igouy

17
@igouy - ประเด็นคือการที่กล่าวว่าไม่มีการใช้รหัสสมมุติลักษณะของโค้ด Java ที่ "เร็วขึ้น" ทำให้ขนานได้ยากยิ่งขึ้นเช่นอัตราส่วนค่าใช้จ่าย / ผลประโยชน์หมายความว่าไม่น่าจะเกิดขึ้นได้เลย Idiomatic Scala ในทางกลับกันการประกาศทางธรรมชาติมากขึ้นสามารถทำให้เกิดขึ้นพร้อมกันได้ไม่มากไปกว่าการเปลี่ยนแปลงเล็กน้อย
Kevin Wright

7
การมีอยู่ของโปรแกรม Java ที่เกิดขึ้นพร้อมกันไม่ได้หมายความว่าโปรแกรม Java ทั่วไปสามารถปรับให้เข้ากับภาวะพร้อมกันได้ง่าย ถ้ามีอะไรฉันจะบอกว่าสไตล์การแยกทางกันโดยเฉพาะนั้นหายากเป็นพิเศษใน Java และจะต้องมีรหัสอย่างชัดเจนในขณะที่การดำเนินการอย่างง่ายเช่นการค้นหาค่าต่ำสุดที่มีอยู่หรือผลรวมของค่าในคอลเลกชันสามารถทำได้เล็กน้อย .parในกาลาโดยเพียงแค่ใช้
Kevin Wright

5
ไม่ฉันอาจไม่ได้ สิ่งนี้เป็นหน่วยการสร้างพื้นฐานสำหรับอัลกอริทึมมากมายและเพื่อให้เห็นว่าอยู่ในระดับต่ำในภาษาและไลบรารีมาตรฐาน (ไลบรารีมาตรฐานเดียวกันที่โปรแกรมทั้งหมดจะใช้ไม่ใช่แค่แบบทั่วไป) เป็นหลักฐานว่าคุณ ' ใกล้ตัวคุณมากขึ้นพร้อมกันเพียงแค่เลือกภาษา ตัวอย่างเช่นการจับคู่กับคอลเลกชันนั้นมีความเหมาะสมกับการขนานและโดยปกติแล้วจำนวนของโปรแกรมสกาล่าที่ไม่ได้ใช้mapวิธีการจะมีขนาดเล็กมาก
เควินไรท์

31

เกมเกณฑ์มาตรฐานภาษาคอมพิวเตอร์:

ทดสอบความเร็ว java / สกาล่า 1.71 / 2.25

ทดสอบหน่วยความจำ java / สกาล่า 66.55 / 80.81

ดังนั้นมาตรฐานนี้บอกว่า java เร็วขึ้น 24% และสกาล่าใช้หน่วยความจำเพิ่มขึ้น 21%

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

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


34
ขนาดโค้ด java / scala 3.39 / 2.21
hammar

22
ระวังตัวเลขเหล่านี้พวกเขาฟังดูแม่นยำมากในความเป็นจริงพวกเขาไม่ได้มีความหมายอะไรเลย มันไม่เป็นถ้า Scala อยู่เสมอ 24% เร็วกว่า Java บนเฉลี่ย ฯลฯ
Jesper

3
ตัวเลขที่อ้างถึง Afaik บ่งบอกถึงสิ่งตรงกันข้าม: Java เร็วกว่าสกาล่า 24% แต่อย่างที่คุณพูด - พวกมันคือ microbenchmarks ซึ่งไม่จำเป็นต้องตรงกับสิ่งที่เกิดขึ้นในแอพจริง และวิธีที่แตกต่างกันหรือวิธีการแก้ปัญหาในภาษาที่แตกต่างกันอาจนำไปสู่โปรแกรมที่เทียบเคียงน้อยที่สุดในที่สุด
ผู้ใช้ไม่รู้จัก

9
"ถ้าสกาล่าทำให้คุณและทีมของคุณ ... " บรรทัดล่าง: คุณจะรู้ว่าหลังจากนั้นไม่ได้มาก่อน :-)
igouy

หน้าวิธีใช้ของเกมเกณฑ์มาตรฐานให้ตัวอย่างของวิธี "เปรียบเทียบความเร็วและขนาดโปรแกรมสำหรับการใช้งาน 2 ภาษา" สำหรับ Scala และ Java หน้าการเปรียบเทียบที่เหมาะสมคือ - shootout.alioth.debian.org/u64q/scala.php
igouy

20

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

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

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

คุณสมบัติการออกแบบที่เลื่อนออกไป:

คุณสมบัติการใช้งานที่รอการตัดบัญชี:

คุณสมบัติการดำเนินการรอการตัดบัญชี: (ขออภัยไม่มีลิงก์)

  • ค่าความขี้เกียจของเธรดที่ปลอดภัย
  • ผ่านโดยชื่อ
  • สิ่งโมนาดิค

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


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

นี่คือสิ่งที่ฉันคิดว่าเป็นแอปเปิ้ลมากกว่าแอปเปิ้ลเทียบเท่ากับตัวอย่าง Java ของเขา:

val bigEnough = array.collect({
    case k: String if k.length > 2 && mapping.contains(k) => mapping(k)
})

ไม่มีคอลเลกชันตัวกลางไม่มีOptionกรณี ฯลฯ นี้ยังเก็บรักษาคอลเลกชันประเภทเพื่อbigEnough's ประเภทคือArray[File]- Array' s collectการดำเนินการอาจจะทำสิ่งที่ตามเส้นของสิ่งที่นายเคอร์รหัส Java ไม่

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

นอกจากนี้:

val bigEnough = array.withFilter(_.length > 2).flatMap(mapping.get)

withFilterวิธีการที่ผมเคยใช้ที่นี่แทนการfilterแก้ไขปัญหาคอลเลกชันกลาง แต่ยังคงมีปัญหาเช่นตัวเลือก


ตัวอย่างหนึ่งของความเร็วในการใช้งานอย่างง่ายใน Scala คือการบันทึก

ใน Java เราอาจเขียนสิ่งที่ชอบ:

if (logger.isDebugEnabled())
    logger.debug("trace");

ในสกาล่านี่เป็นเพียง:

logger.debug("trace")

เนื่องจากพารามิเตอร์ข้อความที่จะดีบั๊กใน Scala มีประเภท " => String" ซึ่งฉันคิดว่าเป็นฟังก์ชั่นที่ไม่ใช้พารามิเตอร์ที่ดำเนินการเมื่อมีการประเมิน แต่เอกสารที่เรียกใช้ Pass-by-name

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

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

สำหรับฉันนี่เป็นชุดรูปแบบที่สอดคล้องกันภายใน Scala


รหัสยากล้มเหลวในการจับภาพว่าทำไม Scala ถึงเร็วกว่าถึงจะเป็นเพียงเล็กน้อย

ฉันรู้สึกว่ามันเป็นการผสมผสานระหว่างการนำโค้ดกลับมาใช้ใหม่และเพดานคุณภาพของรหัสใน Scala

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

ฉันมีความหวังสูงว่าสกาล่าอาจอนุญาตให้ไอน์สไตน์ในหมู่พวกเราใช้ API ที่มีความสามารถมากขึ้นซึ่งอาจแสดงออกผ่านทาง DSL API หลักใน Scala นั้นอยู่ไกลไปตามเส้นทางนี้แล้ว


สิ่งบันทึกของคุณเป็นตัวอย่างที่ดีสำหรับข้อผิดพลาดด้านประสิทธิภาพของ Scala: logger.debug ("trace") สร้างวัตถุใหม่สำหรับฟังก์ชันที่ไม่ใช้พารามิเตอร์
jcsahnwaldt Reinstate Monica

แน่นอน - มันมีผลต่อประเด็นที่เกี่ยวข้องของฉันอย่างไร
เซท

วัตถุดังกล่าวยังสามารถนำมาใช้เพื่อสร้างโครงสร้างการควบคุม IoC ที่โปร่งใสเพื่อประสิทธิภาพ ใช่ผลลัพธ์เดียวกันในทางทฤษฎีเป็นไปได้ใน Java แต่มันจะเป็นสิ่งที่ได้รับผลกระทบอย่างมาก / ทำให้งงงวยวิธีการเขียนรหัส - ดังนั้นข้อโต้แย้งของฉันที่ความสามารถของ Scala ในการชะลอการพัฒนาองค์ประกอบหลายอย่างของซอฟต์แวร์ เร็วกว่าในทางปฏิบัติ vs มีประสิทธิภาพของหน่วยเร็วขึ้นเล็กน้อย
เซท

ตกลงฉันอ่านมันอีกครั้งและฉันก็เขียนว่า "ความเร็วในการประมวลผลอย่างง่าย" - ฉันจะเพิ่มบันทึกย่อ จุดดี :)
Seth

3
คาดการณ์ได้ถ้าคำสั่ง (โดยทั่วไปฟรีในโปรเซสเซอร์ superscalar) เทียบกับการจัดสรรวัตถุ + ขยะ เห็นได้ชัดว่าโค้ด Java เร็วขึ้น (โปรดทราบว่าจะประเมินเงื่อนไขเท่านั้นการดำเนินการจะไม่ถึงคำสั่งบันทึก) ในการตอบสนองต่อ "สำหรับงานของฉันน้ำหนักของวัตถุเล็ก ๆ น้อย ๆ นั้นคุ้มค่าที่จะนำข้อความบันทึก ."
Eloff


10

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

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


7
ฉันเห็นความผิดพลาดแบบลอจิคัลที่นี่: ทั้งสองภาษาคอมไพล์ลงใน bytecode แต่โปรแกรมเมอร์ที่มีประสบการณ์และมือใหม่ - รหัสของพวกเขาคอมไพล์ลงไปที่ bytecode ด้วย - แต่ไม่ใช่ bytecode เดียวกันดังนั้นข้อสรุปที่แตกต่างกัน อาจผิด และในความเป็นจริงในสมัยก่อนสักครู่ห่วงอาจเป็นเร็วกว่ามากในสกาล่ากว่า semantically เทียบเท่าสำหรับห่วง (ถ้าฉันจำได้อย่างถูกต้องมันจะดีกว่ามากในวันนี้) และทั้งคู่ก็ถูกคอมไพล์ด้วยรหัสไบต์แน่นอน
ผู้ใช้ไม่รู้จัก

@user unknown - "a--loop อาจเร็วกว่าใน scala มากกว่า semantically for-loop" - สังเกตว่า Scala benchmarks โปรแกรมเกมเหล่านั้นเขียนด้วย loops
igouy

@igouy: ฉันไม่ได้พูดถึงผลลัพธ์จาก microbenchmark นี้ แต่เกี่ยวกับการโต้แย้ง ข้อความจริงJava and Scala both compile down to JVM bytecode, ซึ่งรวมกับ a soถึงคำแถลงในคำถามที่diffence isn't that big.ฉันต้องการแสดงให้เห็นว่านั่นsoเป็นเพียงแค่การใช้ถ้อยคำโวหารและไม่ใช่ข้อสรุปเชิงโต้แย้ง
ไม่ทราบผู้ใช้

3
คำตอบที่ไม่ถูกต้องอย่างน่าประหลาดใจด้วยคะแนนโหวตสูงอย่างน่าประหลาดใจ
shabunc

4

ตัวอย่าง Java ไม่ใช่สำนวนจริงสำหรับโปรแกรมประยุกต์ทั่วไป รหัสที่ได้รับการปรับให้เหมาะสมดังกล่าวอาจพบได้ในวิธีการไลบรารีระบบ แต่มันจะใช้อาเรย์ของประเภทที่ถูกต้องนั่นคือไฟล์ [] และจะไม่โยน IndexOutOfBoundsException (เงื่อนไขตัวกรองที่แตกต่างกันสำหรับการนับและการเพิ่ม) เวอร์ชันของฉันจะเป็น (เสมอ (!) ที่มีเครื่องหมายปีกกาเนื่องจากฉันไม่ต้องการใช้เวลาหนึ่งชั่วโมงในการค้นหาข้อผิดพลาดซึ่งได้รับการแนะนำโดยการบันทึก 2 วินาทีเพื่อกดปุ่มเดียวใน Eclipse):

List<File> bigEnough = new ArrayList<File>();
for(String s : array) {
  if(s.length() > 2) {
    File file = mapping.get(s);
    if (file != null) {
      bigEnough.add(file);
    }
  }
}

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

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

คลาสย่อยและรหัสการสร้างอินสแตนซ์ไม่ชัดเจนใน Java และจะสามารถอ่านได้อย่างมากใน Scala

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