如何使用Kotlin通道实现自然(又称智能)批处理?
自然的。智能批处理是流处理中的一种技术,它在不影响延迟的情况下优化吞吐量。在并发队列的示例中,使用者能够在某个时刻原子地耗尽所有观察到的项,然后将它们作为批处理。理想情况下,队列应该是有界的,为批量大小提供一个上限,同时向发送方提供反压力 它被称为“自然”批处理,因为没有强制的批处理大小:当流量较低时,它将在每个项目到达后立即处理。在这种情况下,您不需要通过批处理项目来优化吞吐量。当流量增加时,使用者将自动开始处理更大的批处理,从而摊销单个操作(如数据库如何使用Kotlin通道实现自然(又称智能)批处理?,kotlin,kotlinx.coroutines,Kotlin,Kotlinx.coroutines,自然的。智能批处理是流处理中的一种技术,它在不影响延迟的情况下优化吞吐量。在并发队列的示例中,使用者能够在某个时刻原子地耗尽所有观察到的项,然后将它们作为批处理。理想情况下,队列应该是有界的,为批量大小提供一个上限,同时向发送方提供反压力 它被称为“自然”批处理,因为没有强制的批处理大小:当流量较低时,它将在每个项目到达后立即处理。在这种情况下,您不需要通过批处理项目来优化吞吐量。当流量增加时,使用者将自动开始处理更大的批处理,从而摊销单个操作(如数据库INSERT)的固定延迟 我编写了一些实现
INSERT
)的固定延迟
我编写了一些实现基本目标的代码:
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
const val batchLimit = 20
@ObsoleteCoroutinesApi
suspend inline fun <T: Any> ReceiveChannel<T>.consumeBatched(
handleItems: (List<T>) -> Unit
) {
val buf = mutableListOf<T>()
while (true) {
receiveOrNull()?.also { buf.add(it) } ?: break
for (x in 2..batchLimit) {
poll()?.also { buf.add(it) } ?: break
}
handleItems(buf)
buf.clear()
}
}
导入kotlinx.coroutines*
导入kotlinx.coroutines.channels*
const val batchLimit=20
@废弃的公司程序
挂起inline fun ReceiveChannel.consumeBatched(
handleItems:(列表)->单位
) {
val buf=mutableListOf()
while(true){
receiveOrNull()?。也可{buf.add(it)}?:中断
对于(x/2..batchLimit){
poll()?。也可以{buf.add(it)}?:break
}
handleItems(buf)
buf.clear()
}
}
我们可以用以下方法进行测试:
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
fun main() {
val chan = generateMockTraffic()
runBlocking {
chan.consumeBatched { println("Received items: $it") }
}
}
@ExperimentalCoroutinesApi
private fun generateMockTraffic(): ReceiveChannel<Int> {
return GlobalScope.produce(capacity = batchLimit) {
(1..100).forEach {
send(it)
if (it % 10 == 0) {
delay(1)
}
}
}
}
@ObsoleteCoroutinesApi
@实验常规
主要内容(){
val chan=generateMockTraffic()
运行阻塞{
chan.consumerBatched{println(“已接收项目:$it”)}
}
}
@实验常规
private fun generateMockTraffic():ReceiveChannel{
返回GlobalScope.Product(容量=批次限制){
(1..100)forEach{
发送(it)
如果(它%10==0){
延迟(1)
}
}
}
}
consumeBatched()
一次轮询队列中的一个项目,因此必须另外施加批次限制。如果针对Agrona项目这样的并发队列编写,它将更为理想,Agrona项目支持drain
操作
有没有更好的方法与Kotlin频道,从图书馆得到更多的支持
如果不是,这是否会被视为一项需要添加的功能
有没有更好的方法与Kotlin频道,从图书馆得到更多的支持
库不支持此功能
如果不是,这是否会被视为一项需要添加的功能
它取决于所需的API曲面drain
成员不太可能适合通道语义:它约束实现,它应该以某种方式公开drain限制,并为通道提供更多“类似于集合”的API。例如,drain
在不受限制的频道中应该如何表现?是否有可能以有效的方式实施排放
(使用预先设置大小的缓冲区,但避免oom和无限收集)一次,并将其用于任何渠道实施
可以改进的是来自通道的额外提示,例如预期容量和排队元素的计数。它们可以有一个宽松的语义和默认的实现,并像一些合理的可配置上界的drain
扩展的提示。这样的API可以在将来添加,请随意使用