协程(goroutines和kotlin协程)哪个更快?
Kotlin corutines是有限状态机和一些任务运行器(例如,默认的ForkJoinPool)的糖。 https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#implementation-details
换句话说,在java / kotlin运行时中没有运行时协程(但是这可以通过http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html改变)。 Kotlin协同程序只是顺序执行的任务,逐个执行。 每个任务都可以在线程池中的任何线程中执行。
Go运行时支持“协同程序”。 但是goroutines不是真正的协程。 Goroutines不允许在程序中设置收益点。 另外,Go不允许设置自定义线程池。 您只能在默认池中设置线程的大小。
kotlin协程和goroutines之间的第一个区别是Go运行时管理此时正在运行的协程。 当某个IO操作(或同步原语)阻塞了goroutine时,选择下一个Job来执行它。 在JVM中,这种条件下没有智能的工作转换。
因此,Go可以便宜地更改当前正在运行的工作。 Go只需要更改一些registryhttps://groups.google.com/forum/#!msg/golang-nuts/j51G7ieoKh4/wxNaKkFEfvcJ 。 但有人说,JVM可以使用堆栈线程而不是使用寄存器。 所以根本没有保存和加载寄存器。
kotlin协程和goroutines之间的第二个区别是协程types。 Kotlin协程是无堆栈协程。 Goroutines是堆栈协程。 Kotlin协程的所有状态都存储在Kotlin上下文中,并存储在堆中。 Goroutines状态存储在寄存器和线程堆栈中。
我想知道哪些协程(goroutines和kotlin协程)在IO绑定任务中更快? CPU绑定任务? 内存消耗如何?
Kotlin中的协程与Go中的协程不同,所以哪一个更“快”取决于你正在解决的问题以及你正在编写的代码的types。
一般来说,很难预先知道哪一个能更好地处理您手边的问题。 您必须为特定的工作负载运行基准测试。 但是,这里是关键差异的一般总结,应该给你一些指导。
-
Kotlin协程每个简单的实例比Go协程需要的内存少。 Kotlin中一个简单的协程只占用了几十个字节的堆内存,而一个Go程序以4KiB的堆栈空间开始。 这意味着,如果你打算真正实现数以百万计的协同程序,那么Kotlin的协程可能会给你一个与Go相比的优势。 这也使得Kotlin协同程序更适合于非常短暂和小型的任务,如发生器和惰性序列。
-
Kotlin协程可以进入任何堆栈深度,但是每次调用暂停函数都会在堆中为堆栈分配对象。 Kotlin协同程序中的调用堆栈当前是作为堆对象的链接列表实现的。 相反,Go中的goroutines使用线性堆栈空间。 这使得在Go中更高效的悬挂在较深的堆栈上。 所以,如果你正在编写的代码暂停在栈底,你可能会发现goroutines对你来说效率更高。
-
高效的异步IO是一个非常多维的设计问题。 对于某种应用程序而言,效率较高的方法可能无法为另一种应用程序提供最佳性能。 Kotlin协同程序中的所有IO操作都是用Kotlin或Java编写的库实现的。 Kotlin代码提供了大量的IO库。 在Go中,异步IO由Go运行时使用一般Go代码不可用的基元实现。 如果Go方法实现IO操作非常适合您的应用程序,那么您可能会发现,它与Go运行时的紧密集成为您提供了一个优势。 另一方面,在Kotlin中,您可以find一个库,或者自己编写一个以最适合您的应用程序的方式实现异步IO的库。
-
Go运行时在物理OS线程上完全控制调度goroutines的执行。 这种方法的优点是你不必考虑这一切。 使用Kotlin协同程序,您可以对协程的执行环境进行细粒度的控制。 这很容易出错(例如,您可能只是创建太多不同的线程池,并浪费CPU时间来切换它们之间的上下文)。 但是,它使您能够微调您的应用程序的线程分配和上下文切换。 例如,在Kotlin中,很容易在单个操作系统线程(或线程池)中执行整个应用程序或其代码子集,以便完全避免在操作系统线程之间切换上下文,只需编写适当的代码即可。