Về hiệu suất và khả năng tương tác Java: Clojure so với Scala


82

Tôi đã đọc nhiều tài khoản khác nhau về Clojure và Scala và trong khi tôi nhận ra rằng cả hai đều có vị trí của mình. Có một số cân nhắc mà tôi chưa có được lời giải thích đầy đủ khi so sánh cả Clojure với Scala:

1.) Ngôn ngữ nào trong hai ngôn ngữ nói chung nhanh hơn ? Tôi nhận thấy rằng điều này sẽ thay đổi từ tính năng ngôn ngữ này sang tính năng ngôn ngữ khác nhưng đánh giá chung về hiệu suất sẽ hữu ích. Ví dụ: Tôi biết rằng từ điển Python rất nhanh. Nhưng nói chung, đó là một nhiều ngôn ngữ chậm hơn so với Java. Tôi không muốn đi với Clojure và gặp phải vấn đề này trên đường.

2.) Khả năng tương tác với Java như thế nào? Tất cả những gì tôi đã đọc cho đến nay là Scala có các kiểu bộ sưu tập gốc khiến việc tích hợp với một cơ sở mã Java lớn sẽ hơi vụng về, trong khi Clojure tuân theo một cách đơn giản tập trung vào Iterable / Iterator để hoạt động liên thông với các lớp Java. Bất kỳ suy nghĩ / chi tiết về điều này?

Cuối cùng, nếu nó đủ gần giữa clojure và scala, tôi có thể thử cả hai. Một điều về Clojure là ngôn ngữ có vẻ rất đơn giản. Nhưng một lần nữa, Scala có một hệ thống kiểu rất linh hoạt. Nhưng, tôi biết rằng Scala rất nhanh (dựa trên nhiều tài khoản cá nhân). Vì vậy, nếu Clojure chậm hơn đáng kể: Tôi muốn biết sớm hơn là muộn hơn.


1
Với Clojure 1.2, Clojure có thể gọi java mà không tốn phí. Nhìn vào assemblybla.com/wiki/show/clojure/Datatypesassemblybla.com/wiki/show/clojure/New_new . Điều này được thực hiện vì Clojure muốn gần gũi với Java nhưng được thực hiện trong Clojure.
nickik

Câu trả lời:


73

Tôi nghĩ một trong hai ngôn ngữ sẽ đủ nhanh cho bạn. Khi so sánh Python và Java, có vẻ hơi phi lý khi đổ lỗi cho ngôn ngữ này vì sự khác biệt về tốc độ. Java được biên dịch JIT (ngoại trừ trên thiết bị di động *) trong khi Python được thông dịch. Chỉ vì cả hai đều sử dụng mã bytecode không có nghĩa là việc triển khai sẽ có hiệu suất thậm chí có thể so sánh được từ xa. Nhưng cả Scala và Clojure đều là ngôn ngữ JVM nên chúng sẽ có hiệu suất tương tự.

Scala có một vài lợi thế triển khai so với Clojure và tôi mong đợi hiệu suất cao hơn một chút. Mặc dù tĩnh gõ Scala của thường sẽ chuyển thành một lợi thế tốc độ hơn gõ vịt Clojure của, Clojure không loại hỗ trợ gián tiếp mà có thể tăng tốc lên mã đáng kể. Có thể, Scala thông thường nhanh hơn Clojure thông thường, nhưng bạn chỉ cần tối ưu hóa các nút thắt cổ chai. Hầu hết thời gian chạy của một chương trình được tạo ra bởi một lượng nhỏ mã thực tế.

Về Interop w / Java, Scala gần giống với Java hơn nhưng tôi chắc chắn rằng cả hai ngôn ngữ đều tương tác tốt. Trong Lập trình Clojure Stuart Halloway viết: "[bạn có thể truy cập] bất cứ thứ gì bạn có thể tiếp cận từ mã Java. ".

Và kể từ khi tác giả Martin Odersky của Scala viết trình biên dịch Java của Sun, tôi nghĩ rằng không có quả bóng nào bị loại bỏ ở phía Scala. :-)

Bạn sẽ rất khó để chọn ra hai ngôn ngữ tốt hơn, mặc dù tôi cũng thích Ruby. Tại sao bạn lo lắng về cái nào để thử? Tại sao không thử cả hai? Scala có nhiều khả năng trở thành "Java tiếp theo", trong khi thật khó để tưởng tượng rằng Lisp cuối cùng sẽ cất cánh sau hơn 50 năm không làm như vậy. Nhưng rõ ràng là Lisp ở cấp độ trừu tượng độc đáo của riêng nó và Clojure khá đơn giản, vì vậy Scala + Clojure sẽ không khó hơn nhiều so với Scala (khá phức tạp) và tôi chắc chắn rằng bạn sẽ rất vui vì đã làm nó.

Và vì vấn đề đó, chúng tương tác với nhau ...

* dalvik (android's JVM) có trình biên dịch JIT trong phiên bản 2.2 vào năm 2010


6
Huh. Vâng, cảm ơn vì tất cả những hiểu biết sâu sắc. Lúc đầu, tôi ở chế độ mà tôi muốn chỉ chọn một chiếc và chạy với nó. Nhưng vì lý do nào đó, tôi không thể sử dụng cả hai và cho chúng hoạt động với nhau. Vì vậy, có lẽ tôi sẽ chọn cả hai và làm một nhanh đi bộ với họ :-)
Ryan Delucchi

7
Và tôi muốn nói thêm rằng tôi thực sự có một chút "điểm yếu" đối với LISP nên việc Clojure mắc chứng viêm lưỡi gà không đủ để làm tôi sợ hãi.
Ryan Delucchi,

8
Không phải lúc nào cũng đúng khi một ngôn ngữ viết trong JVM sẽ hoạt động ở tốc độ cao nhất. JRuby ban đầu có hiệu suất kinh khủng vì nó là một trình thông dịch được biên dịch sang JVM, không phải mã nguồn. Ngôn ngữ, cũng có thể được đổ lỗi. Các ngôn ngữ được nhập tĩnh thường dễ tối ưu hóa hơn các ngôn ngữ động, v.v.
Bill K

7
-1 "cả Scala và Clojure đều là ngôn ngữ JVM nên chúng sẽ có hiệu suất tương tự" hoàn toàn không có ý nghĩa. Các ngôn ngữ động cần luôn tương tác với các ngôn ngữ tĩnh như Java luôn chậm hơn nhiều (quá tải đi kèm với một chi phí khổng lồ, loại gián tiếp không giải quyết tất cả các vấn đề, vv)
julx

4
@julkiewicz - đơn giản là không đúng khi các ngôn ngữ động luôn chậm hơn nhiều. Nó phụ thuộc vào việc liệu trình biên dịch của bạn có thể thực hiện tốt công việc tối ưu hóa mã được đề cập hay không. Ví dụ, trong Clojure, bạn có thể tính toán số học với các nguyên thủy Java khớp chính xác với hiệu suất Java. Tương tự như vậy, việc gọi một phương thức trên một đối tượng Java gợi ý kiểu cũng nhanh như một lệnh gọi phương thức đối tượng Java. Về cơ bản, trình biên dịch Clojure tạo ra mã bytecode giống như javac đối với mã Java tương đương.
mikera

32

Với JVM hiện tại, Scala có lợi thế hơn về tài khoản được nhập tĩnh, vì JVM hỗ trợ nhập động - phản chiếu - chậm. Trên thực tế, một tính năng Scala phải được thực hiện thông qua các kỹ thuật, kiểu cấu trúc giống nhau, thường bị cảnh báo vì lý do này.

Ngoài ra, Scala chấp nhận các đối tượng có thể thay đổi được và một số thuật toán thực hiện nhanh hơn với khả năng thay đổi.

Vì cả Scala và Java về cơ bản đều là các ngôn ngữ dựa trên lớp, chúng tương tác với nhau dễ dàng hơn. Hoặc, có lẽ, liền mạch hơn. Một lớp Java là một lớp cho Scala và một lớp Scala là một lớp cho Java. Các vấn đề có thể nảy sinh khi nói đến các đĩa đơn của Scala hoặc các thành viên tĩnh của Java, đặc biệt khi có một khuôn khổ liên quan đến việc mong đợi mọi thứ hoạt động theo một cách nhất định.

Vì vậy, tôi sẽ sử dụng Scala trên cả hai tài khoản này . Clojure, theo nhiều cách, là một ngôn ngữ tốt hơn , và nó chắc chắn có những tính năng rất thú vị chưa có (cho đến nay) trên Scala, nhưng bạn gặt hái được những lợi ích như vậy bằng cách hoạt động đầy đủ. Nếu bạn có ý định làm điều đó, thì Clojure rất có thể sẽ tốt hơn. Nếu không, thì có lẽ bạn nên ở lại với Scala.


9
Các tính năng lập trình chức năng của clojure là lý do thuyết phục nhất khiến tôi xem xét ngôn ngữ này. Tôi đang đạt đến điểm: nếu tôi không viết mã thứ gì đó theo kiểu chức năng - thì tại sao tôi lại bận tâm đến một ngôn ngữ kịch bản được nhúng trong Java? Tôi đã có Python bên cạnh để thực hiện các tác vụ nhanh chóng và khó khăn.
Ryan Delucchi

9
Sau đó, đi với Clojure.
Daniel C. Sobral

"ngôn ngữ kịch bản nhúng trong Java". Hãy biện minh.
12

@Daniel: Xin lỗi vì nhầm lẫn. Ý tôi là nhận xét về Ryan Delucchi. Anh ấy nói rằng Scala là một "ngôn ngữ kịch bản được nhúng trong Java", mà tôi không mua. (Trừ khi ý của anh ấy là Clojure, mà tôi không biết về nó).
12

@ Jus12 Tôi hiểu điều đó có nghĩa là anh ấy đang sử dụng những ngôn ngữ này làm ngôn ngữ kịch bản JVM và, cho rằng, anh ấy không thấy bất kỳ lợi thế nào trong chúng so với Python trừ khi anh ấy hoạt động. Và một lần nữa, tôi không phải là anh ấy, vì vậy tôi chỉ có thể đoán.
Daniel C. Sobral

20

Lưu ý rằng Clojure và Scala là hai loại ngôn ngữ lập trình hoàn toàn khác nhau - Clojure là một ngôn ngữ chức năng giống như Lisp, nó không hướng đối tượng. Scala là một ngôn ngữ hướng đối tượng có các tính năng lập trình chức năng.

Theo ý kiến ​​của tôi, các tính năng và khái niệm của một ngôn ngữ (chức năng, OO, ...) là tiêu chí quan trọng hơn nhiều để lựa chọn một ngôn ngữ hơn là hiệu suất (của một cách triển khai cụ thể của ngôn ngữ đó) - tôi hiểu rằng bạn không muốn bị mắc kẹt trong một ngôn ngữ mà không có sẵn cách triển khai hiệu quả.

Tôi muốn dùng Scala, vì nó hướng đối tượng nhưng cũng cho phép bạn học lập trình chức năng (nếu bạn quan tâm đến điều đó). Mặt khác, nếu bạn không quan tâm đến OO và bạn muốn học lập trình chức năng "thuần túy", hãy thử Clojure.


9
Rõ ràng là bạn chưa sử dụng Clojure. Clojure là Hướng đối tượng như Scala là Chức năng. Bạn có thể triển khai một giao diện, mở rộng một lớp, khai báo các hàm riêng và tĩnh, v.v. ( clojure.org/java_interop ).
Richard Clayton

28
Những thứ đó tồn tại trong Clojure để có khả năng tương tác với Java, nhưng các lớp và đối tượng rõ ràng không phải là tính năng chính của Clojure. Bạn không tạo các lớp và thiết kế dự án của mình theo cách OO nếu bạn định lập trình trong Clojure.
Jesper

>> "hơn hiệu suất". Vấn đề là: điều gì sẽ xảy ra khi - sâu trong một dự án - bạn phát hiện ra rằng hiệu suất của mình kém - và không phải do chỉ một phần nhỏ của nó (mà bạn đã dự định chuyển đổi sang java cho chính dự án đó). Mặc dù tôi không có ý định nói ở đây là "không sử dụng áo choàng - thời kỳ ..", nhưng rõ ràng rằng áo choàng là một rủi ro lớn hơn trong đấu trường biểu diễn. Có rất nhiều cơ hội cho mã cấp ứng dụng mà điều đó không quan trọng: nhưng cũng có nhiều cơ sở mã khuôn khổ / đa luồng / xử lý chuyên sâu, nơi đó sẽ là trách nhiệm.
StephenBoesch

@javadba Ý kiến ​​rằng clojure không tốt cho mã đa luồng cấp thấp có vẻ khá tùy tiện. Clojure được thiết kế sao cho rất khó mắc lỗi lập trình đa luồng. Các dữ liệu và STM tính năng bất biến mà là cốt lõi để ngôn ngữ clojure là một cái gì đó không có sẵn trong lõi Scala, và họ làm cho nó nhiều ít có khả năng rằng một lập trình viên vô tình chèn một điều kiện chủng tộc hay bế tắc vào mã của họ. Chắc chắn điều này có giá trị hơn một vài mili giây thời gian chạy mà bạn có thể nhận được từ một ngôn ngữ được nhập tĩnh như Scala hoặc Java.
nben

"Chắc chắn điều này có giá trị hơn vài ms thời gian chạy" .. Điều đó phụ thuộc vào quy mô của dữ liệu. một vài ms là tốt cho một vài bản ghi. nhân với hàng trăm triệu ..
StephenBoesch

16
  1. Idiomatic Scala nhanh hơn Idiomatic Clojure, và sẽ vẫn như vậy.
  2. Cả Scala và Clojure đều dễ dàng sử dụng trên Java. Không ngồi tốt bên dưới nó.

Nếu mã của bạn quan trọng về thời gian hoặc không gian xuyên suốt, hãy sử dụng Java. Nhưng nó không phải, ngay cả khi bạn nghĩ nó là.

Các máy tính Ngôn ngữ Benchmark game rụng lông rất ít ánh sáng vào chi phí tài nguyên đúng Clojure của. Không có cấu trúc dữ liệu Clojure nào được sử dụng. Các trừu tượng về chức năng và trình tự không xuất hiện.

Clojure có vẻ đơn giản. Nó không phải, nhưng nó là biểu cảm. Nó có thể chạy chậm hơn Java năm lần, nhưng nguồn nhỏ hơn năm lần (YMMV). Đối với hầu hết các ứng dụng, đây là một chiến thắng lớn. Nhưng đối với một số người và đối với một số bộ phận của nhiều người khác, đó là một mất mát tàn khốc.

Với kinh nghiệm về ngôn ngữ Clojure, tôi tin rằng có thể nói trước liệu vấn đề của bạn có được giải quyết rõ ràng thành một phần có thể được diễn đạt ngắn gọn và đầy đủ (về mặt hiệu suất) trong Clojure hay không và một phần cần thực hiện trong Java.

  • Bạn có thể học Scala lite: viết các thành ngữ Java trong Scala. Bạn sẽ hiểu được sự ngắn gọn, cú pháp dễ nhìn hơn và một hệ thống kiểu phức tạp nhất quán.
  • Không có cái gọi là Clojure lite: viết các thành ngữ Java trong Clojure là hoàn toàn vô nghĩa. Tất cả những gì bạn sẽ nhận được là Java chậm, khó hiểu vì nó cắt ngang các thành ngữ được sử dụng để diễn đạt.

Scala đã được cho là Java được thực hiện đúng . Clojure không giống Java. Bạn có thể nói rằng Lisp đã thực hiện đúng - một sự táo bạo, một số người sẽ nói là phi lý, khẳng định - điều này có thể trở thành sự thật.


4
Câu trả lời này làm sáng tỏ sự khác biệt thực sự và điểm mạnh / điểm yếu của cả hai. Nó được viết không phải theo cách biện hộ theo tỷ lệ cũng như ngụy biện mà là theo cách xác thực.
StephenBoesch

15

Số liệu thống kê được tạo ra bởi " Trò chơi điểm chuẩn ngôn ngữ máy tính " là những thống kê tốt nhất mà bạn có thể tìm thấy.

Chúng rất chuyên sâu và bạn có thể so sánh nhiều ngôn ngữ. Vấn đề là họ không che Clojure :(

Điều đó nói rằng, khá dễ dàng để gửi bất cứ thứ gì - tất cả đều là mã nguồn mở.

Các số liệu thống kê nói rằng Scala khá nhanh nhẹn.


9
Của bạn đây. Chậm hơn 2-25 lần so với Java, bộ nhớ nhiều hơn 2-30 lần và kích thước mã thường lớn hơn Java. Có vẻ như nó có thể so sánh với Python trong đó Scala rất gần với Java. Tôi muốn nói rằng Scala là người chiến thắng khá rõ ràng và Clojure chậm hơn đáng kể - trừ khi bài kiểm tra Clojure được viết kém.
Bill K

2
Có vẻ như hiện tại điểm chuẩn đã bao gồm Clojure (nhận xét của OP là một năm tuổi). Và kết quả không đáng khích lệ. Scala là con đường để đi.
Martin

4
Các nhận xét ở trên đã hơi lỗi thời - Tính đến giữa năm 2012, Clojure đã thu hẹp khoảng cách về cơ bản, nó hiện chỉ còn trung bình khoảng 2x Java.
mikera

9

Về khả năng tương tác, tôi không thể nói cho Clojure, nhưng tôi hy vọng nó sẽ ở trong tình huống tương tự như Scala.

Gọi Java từ Scala thật dễ dàng.

Có thể dễ dàng gọi Scala từ Java miễn là bạn tuân thủ API bên ngoài của mình với các điểm chung giữa Scala và Java. Ví dụ, một đối tượng Scala được sử dụng theo một số cách giống như các phương thức tĩnh trong Java, nhưng nó không giống như vậy. Các lớp Scala có thể biên dịch thành một số lớp có tên trông ngộ nghĩnh trong Java.

Bạn sẽ không muốn trộn và kết hợp nhiều. Xây dựng thành phần trong Scala hoặc Clojure sử dụng nhiều thư viện Java là rất khả thi. Tất nhiên, bạn có thể gọi thành phần này từ Java, nhưng điều bạn sẽ không muốn làm là cố gắng sử dụng API Scala dành cho các chương trình Scala từ Java.

SVN khẳng định là "CVS thực hiện đúng". Theo quan điểm của tôi, Scala là Java được thực hiện đúng.


19
vậy clojure là git?
Ron

1
@Ron haha, tôi cũng nghĩ y như vậy.
KoW

2
Trên thực tế các bộ sưu tập của Clojure là git-ish
Joe Lehmann

2

Số tháng 11 năm 2010 của PragPub thảo luận về khả năng tương tác Clojure-Java. Việc gọi các phương thức Java là đơn giản, nhưng việc mở rộng các lớp / giao diện Java thì hoàn toàn khác.

Mặt khác, Scala gần với Java hơn nhiều. Khả năng tương tác Scala-Java được xây dựng tại http://www.codecommit.com/blog/java/interop-between-java-and-scala

Việc gọi mã Java và mở rộng các lớp / giao diện Java hoạt động giống như cách gọi mã Scala. Một số điểm khó khăn có thể là một số trường hợp khó xử lý với các generic của Java, vì hệ thống kiểu của Scala mạnh hơn nhiều so với Java. Tạo getters và setters tuân theo quy ước Java Bean yêu cầu chú thích .

Việc gọi Scala từ Java hầu hết đều đơn giản, nhưng ví dụ, các đối tượng đồng hành của Scala yêu cầu biết cách chúng được biên dịch thành bytecode. Ngoài ra việc sử dụng các đặc điểm với các phương thức không trừu tượng từ Java sẽ phức tạp và việc gọi các phương thức với các ký tự đặc biệt sẽ yêu cầu biết chúng được mã hóa như thế nào trong bytecode.


1

Bây giờ (tính đến tháng 5 năm 2010) đáng để đăng nhập vào nhánh 1.2 mới nhất của Clojure - điều này bao gồm nhiều hỗ trợ bổ sung cho các kiểu nguyên thủy và nhập tĩnh (thông qua các gợi ý và giao thức kiểu khác nhau).

Sự hiểu biết của tôi là bạn có thể sử dụng các tính năng này khi cần để có được tốc độ tương đương với việc viết chính xác cùng một đoạn mã trong Java thuần túy.


2
Đồng thời, @specializedkỹ thuật trong Scala 2.8 sắp tới đang mang lại một cải tiến tương tự cho các thư viện Scala. Và với tư cách là một cơ sở ngôn ngữ, nó có sẵn cho tất cả các mã, không chỉ thư viện tiêu chuẩn.
Randall Schulz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.