2017-10-21 44 views
8

Kotlin corutines là đường cho máy trạng thái hữu hạn và một số nhân viên nhiệm vụ (ví dụ, mặc định ForkJoinPool). https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#implementation-detailsLoại coroutines nào (goroutines và kotlin coroutines) nhanh hơn?

Nói cách khác, không có thời gian chạy coroutines trong thời gian chạy java/kotlin (nhưng điều này có thể thay đổi với http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html). Kotlin coroutine chỉ là tuần tự các nhiệm vụ, được thực hiện từng cái một. Mỗi tác vụ có thể được thực hiện trong bất kỳ luồng nào từ nhóm luồng.

Thời gian chạy hỗ trợ "coroutines". Nhưng goroutines không phải là coroutines thực sự. Goroutines không cho phép đặt điểm lợi nhuận trong chương trình. Ngoài ra, Go không cho phép đặt nhóm chủ đề tùy chỉnh. Bạn có thể chỉ đặt kích thước của chuỗi trong nhóm mặc định.

Sự khác biệt đầu tiên giữa corotines kotlin và goroutines là thời gian chạy quản lý coroutine đang chạy tại thời điểm này. Khi goroutine bị chặn tại một số hoạt động IO (hoặc đồng bộ hóa nguyên thủy), Go lựa chọn tiếp theo Công việc để thực hiện nó. Trong JVM không có chuyển đổi công việc trí tuệ trong các điều khoản như vậy.

Vì lý do này, Go có thể thay đổi công việc hiện đang chạy với giá rẻ. Go chỉ thay đổi vài đăng ký https://groups.google.com/forum/#!msg/golang-nuts/j51G7ieoKh4/wxNaKkFEfvcJ. Nhưng một số người nói rằng, JVM có thể sử dụng chồng chủ đề thay vì sử dụng thanh ghi. Vì vậy, không có tiết kiệm và tải đăng ký ở tất cả.

Sự khác biệt thứ hai giữa kotlin coroutines và goroutines là loại coroutines. Corryines Kotlin là coroutines stackless. Goroutines là các coroutines xếp chồng lên nhau. Tất cả các trạng thái của các coroutines Kotlin được lưu trữ trong bối cảnh Kotlin, được lưu trữ trong đống. Trạng thái Goroutines được lưu trữ trong thanh ghi và ngăn xếp luồng.

Tôi muốn biết, coroutines nào (goroutines và kotlin coroutines) nhanh hơn trong các nhiệm vụ ràng buộc IO? Các nhiệm vụ ràng buộc CPU? Điều gì về tiêu thụ bộ nhớ?

+0

Sự khác biệt giữa "coroutines xếp chồng lên nhau" và "corodines không có ngăn xếp" không được xác định và khắc phục. Xem phần nói chuyện JVMLS của tôi để biết chi tiết: https://www.youtube.com/watch?v=3xalVUY69Ok –

Trả lời

24

Coroutines trong Kotlin được thực hiện theo cách khác với goroutines trong Go, vì vậy cái nào "nhanh hơn" phụ thuộc vào vấn đề bạn đang giải quyết và loại mã bạn đang viết.

Nói chung, rất khó để nói trước cái nào sẽ hoạt động tốt hơn cho một vấn đề bạn có trong tầm tay. Bạn phải chạy điểm chuẩn cho khối lượng công việc cụ thể của bạn để tìm ra nó. Tuy nhiên, đây là một bản tóm tắt chung về những khác biệt chính nên cung cấp cho bạn một số hướng dẫn.

  • Kotlin coroutines yêu cầu ít bộ nhớ hơn cho mỗi trường hợp đơn giản hơn Go goroutines. Một coroutine đơn giản trong Kotlin chỉ chiếm một vài chục byte bộ nhớ heap, trong khi goroutine Go bắt đầu với 4KiB của không gian ngăn xếp. Nó có nghĩa là, nếu bạn đang có kế hoạch để có hàng triệu coroutines, sau đó coroutines trong Kotlin có thể cung cấp cho bạn một cạnh so với Go. Nó cũng làm cho correines Kotlin phù hợp hơn cho các nhiệm vụ rất ngắn ngủi và nhỏ như máy phát điện và các trình tự lười biếng.

  • Kotlin coroutines có thể đi đến bất kỳ chiều sâu ngăn xếp, tuy nhiên mỗi invocation của chức năng đình chỉ phân bổ đối tượng trong đống cho ngăn xếp của nó. Một ngăn xếp yêu cầu trong các coroutines Kotlin hiện được thực hiện như một danh sách liên kết của các đối tượng đống. Ngược lại, goroutines trong Go sử dụng không gian ngăn xếp tuyến tính. Điều này làm cho hệ thống treo trên ngăn xếp sâu hiệu quả hơn trong Go. Vì vậy, nếu mã bạn đang viết treo rất sâu xuống ngăn xếp, bạn có thể thấy rằng goroutines hiệu quả hơn cho bạn.

  • IO không đồng bộ hiệu quả là một vấn đề thiết kế rất đa chiều. Cách tiếp cận hiệu quả cho một loại ứng dụng có thể không mang lại hiệu suất tốt nhất cho một ứng dụng khác. Tất cả các hoạt động IO trong các coroutine Kotlin được thực hiện bởi các thư viện được viết bằng Kotlin hoặc Java.Có rất nhiều thư viện IO có sẵn cho mã Kotlin. Trong Go không đồng bộ IO được thực hiện bởi thời gian chạy Go sử dụng nguyên thủy mà không có sẵn cho mã Go chung. Nếu Go tiếp cận để thực hiện các hoạt động IO rất phù hợp với ứng dụng của bạn, thì bạn có thể thấy rằng sự tích hợp chặt chẽ của nó với thời gian chạy Go mang đến cho bạn một lợi thế. Ở phía bên kia, trong Kotlin bạn có thể tìm thấy một thư viện hoặc viết một bản thân thực hiện IO không đồng bộ theo cách phù hợp nhất với ứng dụng của bạn.

  • Thời gian chạy thực hiện kiểm soát hoàn toàn việc lập kế hoạch thực thi goroutines trên các chuỗi hệ điều hành vật lý. Ưu điểm của phương pháp này là bạn không phải suy nghĩ về tất cả. Với các coroutines Kotlin, bạn có quyền kiểm soát chi tiết về môi trường thực thi của các coroutines của bạn. Đây là lỗi dễ xảy ra (ví dụ: bạn có thể chỉ cần tạo quá nhiều nhóm luồng khác nhau và lãng phí thời gian CPU của bạn trên bối cảnh chuyển đổi giữa chúng). Tuy nhiên, nó cung cấp cho bạn khả năng tinh chỉnh phân bổ luồng và chuyển ngữ cảnh cho ứng dụng của bạn. Ví dụ, trong Kotlin, bạn có thể dễ dàng thực thi toàn bộ ứng dụng hoặc một tập hợp con của mã trong một chuỗi hệ điều hành duy nhất (hoặc nhóm luồng) để tránh hoàn toàn việc chuyển đổi giữa các luồng hệ điều hành bằng cách viết mã thích hợp cho điều đó.

+0

«Không có cách nào để nói bằng mã" chạy các goroutines này trên cùng một chuỗi hệ điều hành ".» Không đúng 100% : các cuộc gọi 'runtime.LockOSThread()' khóa goroutine gọi tới luồng hệ điều hành mà nó hiện đang chạy. Điều này sẽ đảm bảo rằng goroutine gọi sẽ luôn được lên lịch trên cùng một luồng đó và không có goroutine nào khác. OTOH, ngoại trừ trường hợp rất hiếm, điều này là không cần thiết, và trên thực tế thường phản tác dụng khi bộ lập lịch Go cố gắng hết sức để đảm bảo một goroutine bị loại bỏ khỏi một luồng được lên lịch lại, nếu có thể. – kostix

+1

@Max, hãy xem xét đọc [bài luận cổ điển này] (http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/) về sự khác biệt giữa đồng thời-as-a-library và đồng thời-qua-thời gian chạy-scheduler phân biệt (ở đây: Java + bất cứ điều gì vs Go). – kostix

+0

@kostix Cảm ơn. Sửa chữa, bằng cách loại bỏ phần này cho chính xác. –

Các vấn đề liên quan