当前位置:网站首页>Deep dive kotlin synergy (18): hot and cold data flow
Deep dive kotlin synergy (18): hot and cold data flow
2022-06-30 10:52:00 【RikkaTheWorld】
Series eBook : Portal
Kotlin At first, there was only Channel, But the creator realized that this was not enough . Channel Is a kind of thermal data flow , But we often need cold data flow .
Understanding the difference between hot data flow and cold data flow can help us learn better Flow And other related technologies , Because most of the data sources you use everyday fall into one of these two categories . aggregate (List、Set) It's hot , And sequence and Java Stream It's cold .Channel It's hot , and Flow and RxJava The flow is cold .
Thermal data flow | Cold data flow |
---|---|
Collections(List, Set) | Sequence, Stream |
Channel | Flow, RxJava streams |
heat vs cold
Hot data flow is urgent 、 Instant , And consumers are independent , Production and storage elements . Cold data flow is lazy , Perform actions on demand , No need to store anything
We can use lists ( heat ) And sequence ( cold ) When I learned about these differences . The builder and operation of hot data flow are started immediately , In the cold data stream , Elements are not produced until they are needed .
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val l = buildList {
repeat(3) {
add("User$it")
println("L: Added User")
}
}
val l2 = l.map {
println("L: Processing")
"Processed $it"
}
val s = sequence {
repeat(3) {
yield("User$it")
println("S: Added User")
}
}
val s2 = s.map {
println("S: Processing")
"Processed $it"
}
}
// L: Added User
// L: Added User
// L: Added User
// L: Processing
// L: Processing
// L: Processing
therefore , Cold data flow ( Such as Sequence
、Stream
or Flow
):
- It could be infinite
- Use as few operations as possible
- Use less memory ( There is no need to allocate all intermediate set products )
Sequence processing does less , Because it delays processing elements . It also works in a very simple way : Each intermediate operation ( Such as map
or filter
) Just for decorating the front sequence . The terminal operation is the end point to complete all the work . Please see the following example , Usage sequence ,find
Will inquire about map
The first qualified element after . It is from sequenceOf
( return 1) Returned sequence , Then map it (1*1 To 1), And return the result to the filter find
. The filter checks whether the element meets its criteria . If the element does not satisfy the condition , The filter will ask again and again . Until you find the right element .
This is very different from the handling of lists , In each intermediate step of list processing, it is necessary to calculate and return a completely processed intermediate set product . This is the difference in the order in which the collection processes elements 、 Need more memory 、 Reasons why more actions may be required ( As shown in the following example ).
fun m(i: Int): Int {
print("m$i ")
return i * i
}
fun f(i: Int): Boolean {
print("f$i ")
return i >= 10
}
fun main() {
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map {
m(it) }
.find {
f(it) }
.let {
print(it) }
// m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 f1 f4 f9 f16 16
sequenceOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map {
m(it) }
.find {
f(it) }
.let {
print(it) }
// m1 f1 m2 f4 m3 f9 m4 f16 16
}
This means that a list is a collection of elements , The sequence is just the definition of the operator set of the element . Thermal data flow :
- Ready to use ( Every operation is a terminal operation )
- You do not need to recalculate the result when using it multiple times
fun m(i: Int): Int {
print("m$i ")
return i * i
}
fun main() {
val l = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map {
m(it) } // m1 m2 m3 m4 m5 m6 m7 m8 m9 m10
println(l) // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
println(l.find {
it > 10 }) // 16
println(l.find {
it > 10 }) // 16
println(l.find {
it > 10 }) // 16
val s = sequenceOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map {
m(it) }
println(s.toList())
// [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
println(s.find {
it > 10 }) // m1 m2 m3 m4 16
println(s.find {
it > 10 }) // m1 m2 m3 m4 16
println(s.find {
it > 10 }) // m1 m2 m3 m4 16
}
Java Flow and Kotlin Sequences have the same characteristics , They are all cold data streams .
hot channel, It's cold flow
It's time to get back to the process . establish flow The easiest way is to use a builder , It is similar to produce
function , This function is called flow
:
val channel = produce {
while (true) {
val x = computeNextValue()
send(x)
}
}
val flow = flow {
while (true) {
val x = computeNextValue()
emit(x)
}
}
These builders are conceptually equivalent , But because of channel and flow There is a big difference in their behavior , There are also important differences between these two functions . Take a look at the following example ,channel It's hot , So they start counting immediately . This calculation needs to start with a single coroutine . That's why produce
Need to be a collaboration builder , It is defined as CoroutineScope
Extension function on . The calculation starts immediately , But because the default buffer size is 0(RENDEZVOUS
), So it will be suspended soon , Until the consumer in the following example is ready . Be careful , When there is no receiver , There is a difference between stopping production and producing on demand .channel As a thermal data stream , Generate elements independently of their consumers , And then store them . They don't care how many consumers there are , Because each element can only be received once . After the first receiver consumes all the elements , The second receiver will find an empty 、 It's closed channel, That's why it doesn't receive any elements at all .
private fun CoroutineScope.makeChannel() = produce {
println("Channel started")
for (i in 1..3) {
delay(1000)
send(i)
}
}
suspend fun main() = coroutineScope {
val channel = makeChannel()
delay(1000)
println("Calling channel...")
for (value in channel) {
println(value) }
println("Consuming again...")
for (value in channel) {
println(value) }
}
// Channel started
// (1 sec)
// Calling channel...
// 1
// (1 sec)
// 2
// (1 sec)
// 3
// Consuming again...
Use Flow It is very different to do the same . Because it is a cold data stream . So production is on demand . It means flow Not a collaboration builder , There is no need for any treatment . It's just a definition of using terminal operations ( Such as collect
) The instruction set of how the element should be produced . It runs on the scope that performs its terminal operations ( It starts with the... Of the suspended function continuation Get scope in , It's like coroutineScope Like other coprocessor scoped functions ), This is flow
The builder does not need a CoroutineScope
Why .Flow Each terminal operation on the will start from scratch . Please carefully compare the above and the following examples , Because they show channel and flow The key difference between :
private fun makeFlow() = flow {
println("Flow started")
for (i in 1..3) {
delay(1000)
emit(i)
}
}
suspend fun main() = coroutineScope {
val flow = makeFlow()
delay(1000)
println("Calling flow...")
flow.collect {
value -> println(value) }
println("Consuming again...")
flow.collect {
value -> println(value) }
}
// (1 sec)
// Calling flow...
// Flow started
// (1 sec)
// 1
// (1 sec)
// 2
// (1 sec)
// 3
// Consuming again...
// Flow started
// (1 sec)
// 1
// (1 sec)
// 2
// (1 sec)
// 3
RxJava Flow and Kotlin Of Flow There are many similarities , Some people even say , Flow It can be called “RxCoroutines”.
summary
Most data sources are either hot or cold :
- Heat data is urgent , They produce elements as quickly as possible and store them . The elements they create are independent of their consumers , They are collections (
List
、Set
) and channel - Cold data flow is inert , They process elements on demand on terminal operations , All intermediate function knowledge defines what should be done ( Usually in decorative mode ), They usually do not store elements , Instead, create elements as needed , They have very few operations , It could be infinite , They create 、 The process of processing elements is usually next to the consumption process . These elements are
Sequence
、Java Stream
,Flow
andRxJava flow
(Observable
、Single
etc. )
This explains. Channel and Flow The essential difference . It is time to discuss the features supported by the latter .
边栏推荐
- Skill combing [email protected] control a dog's running on OLED
- LVGL 8.2 Simple Colorwheel
- 前嗅ForeSpider教程:抽取数据
- Gd32 RT thread flash driver function
- I found a wave of "alchemy artifact" in the goose factory. The developer should pack it quickly
- Q-Learning笔记
- js常见问题
- 数据库什么时候需要使用索引【杭州多测师】【杭州多测师_王sir】
- 如何解决跨域
- The performance of arm's new CPU has been improved by 22%, up to 12 cores can be combined, and the GPU is first equipped with hardware optical tracking. Netizen: the gap with apple is growing
猜你喜欢
【深度学习】深度学习检测小目标常用方法
电商两位大佬花边新闻刷屏,代表电商回归正常,将有利于实体经济
Remember the experience of an internship. It is necessary to go to the pit (I)
[email protected] somatosensory manipulator"/>
Skill combing [email protected] somatosensory manipulator
CSDN博客运营团队2022年H1总结
【STL源码剖析】迭代器
China will force a unified charging interface. If Apple does not bow its head, iPhone will be kicked out of the Chinese market
智能DNA分子纳米机器人模型来了
Mysql database foundation: views and variables
Dell et Apple, deux entreprises de PC établies, se sont effondrées rapidement
随机推荐
Mysql database foundation: TCL transaction control language
TypeScript–es5中的类,继承,静态方法
What is erdma as illustrated by Coptic cartoon?
LVGL 8.2 Image
在 sCrypt 中实现高效的椭圆曲线点加法和乘法
Machine learning interview preparation (I) KNN
LVGL 8.2 re-coloring
CVPR 2022 | Tsinghua & bytek & JD put forward BRT: Bridging Transformer for vision and point cloud 3D target detection
19:00 p.m. tonight, knowledge empowerment phase 2 live broadcast - control panel interface design of openharmony smart home project
运动App如何实现端侧后台保活,让运动记录更完整?
pytorch 筆記 torch.nn.BatchNorm1d
经典面试题:负责的模块,针对这些功能点你是怎么设计测试用例的?【杭州多测师】【杭州多测师_王sir】...
List介绍
File sharing server
I found a wave of "alchemy artifact" in the goose factory. The developer should pack it quickly
CSDN blog operation team 2022 H1 summary
安徽《合肥市装配式建筑施工图审查设计深度要求》印发;河北衡水市调整装配式建筑预售许可标准
Skill combing [email protected] voice module +stm32+nfc
mysql数据库基础:视图、变量
程序员需知的 59 个网站