我正在学习akka流,我不确定完全理解这些2代码在2核和8 GB RAM的笔记本电脑上运行时的性能差异。
val f = Source(1 to numberOfFiles)
.mapAsyncUnordered(numberOfFiles) { _ =>
val fileName = UUID.randomUUID().toString
println(fileName)
Source(1 to numberOfCustomers).mapAsyncUnordered(numberOfCustomers){ _ =>
val rMsisdn = TestUtils.randomString(8)
Future(List(1 to Random.nextInt(20)).map{ i=>
val rCdr= RandomCdr(rMsisdn)
ByteString(s"${rCdr.msisdn};${rCdr.dateTime};${rCdr.peer};${rCdr.callType};${rCdr.way};${rCdr.duration}\n")
}.fold(ByteString())(_ concat _))
}.runWith(FileIO.toPath(Paths.get(s"/home/reactive/data/$fileName")))
}
.runForeach(io=> println(io.status))
和这一个:
val f = Source(1 to numberOfFiles)
.mapAsyncUnordered(numberOfFiles) { _ =>
val fileName = UUID.randomUUID().toString
println(fileName)
Source(1 to numberOfCustomers).map{ _ =>
val rMsisdn = TestUtils.randomString(8)
List(1 to Random.nextInt(20)).map{ i=>
val rCdr= RandomCdr(rMsisdn)
ByteString(s"${rCdr.msisdn};${rCdr.dateTime};${rCdr.peer};${rCdr.callType};${rCdr.way};${rCdr.duration}\n")
}.fold(ByteString())(_ concat _)
}.runWith(FileIO.toPath(Paths.get(s"/home/reactive/data/$fileName")))
}
.runForeach(io=> println(io.status))
第二个提供更好的性能,并且随着更多负载(更多要写入的文件和要生成的客户),差异变得越来越重要。 我的假设是随机生成并不复杂,因此将其与mapAsync并行化的成本要高于仅按顺序运行它。我对吗 ? 我不明白的是,差异随着客户数量的增加而增加。我越多,顺序生成和并行生成之间的差异就越大。
它是否也来自我在流中有流的事实?将2级并行性相互存在是否效率低下?
感谢您的解释,如果您有任何建议来调整此代码,请不要犹豫!
修改
按照建议使用flatMapConcat进行新的尝试,但我仍然遇到文件名问题(不编译)。我不知道如何使用元组的第一个元素作为接收器的文件名?
val f = Source(1 to numberOfFiles)
.map{ i =>
val fileName = UUID.randomUUID().toString
println(fileName)
fileName
}
.flatMapConcat { f =>
Source(1 to numberOfCustomers).map{ p =>
val rMsisdn = TestUtils.randomString(8)
(f,List(1 to Random.nextInt(20)).map{ i=>
val rCdr= RandomCdr(rMsisdn)
ByteString(s"${rCdr.msisdn};${rCdr.dateTime};${rCdr.peer};${rCdr.callType};${rCdr.way};${rCdr.duration}\n")
}.fold(ByteString())(_ concat _))
}
}
.runWith(FileIO.toPath(Paths.get(s"/home/reactive/data/$fileName")))