【发布时间】:2020-10-29 00:40:06
【问题描述】:
我有这样的东西(这是https://github.com/typelevel/fs2 的一个例子,我的补充,我用 cmets 标记):
import cats.effect.{Blocker, ExitCode, IO, IOApp, Resource}
import fs2.{io, text, Stream}
import java.nio.file.Paths
object Converter extends IOApp {
val converter: Stream[IO, Unit] = Stream.resource(Blocker[IO]).flatMap { blocker =>
def fahrenheitToCelsius(f: Double): Double =
(f - 32.0) * (5.0/9.0)
io.file.readAll[IO](Paths.get("testdata/fahrenheit.txt"), blocker, 4096)
.balanceAvailable // my addition
.map ( worker => // my addition
worker // my addition
.through(text.utf8Decode)
.through(text.lines)
.filter(s => !s.trim.isEmpty && !s.startsWith("//"))
.map(line => fahrenheitToCelsius(line.toDouble).toString)
.intersperse("\n")
.through(text.utf8Encode)
.through(io.file.writeAll(Paths.get("testdata/celsius.txt"), blocker))
) // my addition
.take(4).parJoinUnbounded // my addition
}
def run(args: List[String]): IO[ExitCode] =
converter.compile.drain.as(ExitCode.Success)
}
如果fahrenheit.txt 和例如一样大。 300mb 原始代码的执行需要几分钟。看来我的代码并没有更快。我怎样才能提高它的性能?运行时有大量的未使用 CPU 电源,磁盘是SSD,所以我不知道为什么它这么慢。我不确定我是否正确使用了balance。
【问题讨论】:
-
如果你有很多线程写入同一个文件,你不会赢太多,特别是因为这个工作不是真正的 cpu 绑定。
-
我已经在我的硬件上检查了
dd if=fahrenheit.txt of=fahrenheit2.txt需要 5 秒(所以它只是一个没有任何转换的线程,纯 IO 操作)。虽然我同意提高性能并不像增加线程那么容易,但我认为可以提供缓冲区或其他可以减少所需时间的机制的组合。 -
也许你可以增加读取缓冲区大小。反正 fs2 可能没有 dd 快。
标签: scala fs2 cats-effect