如何用Sink提高代码性能?

use*_*977 6 scalaz-stream

我对scalaz-streams汇有奇怪的观察.他们工作缓慢.有谁知道为什么会这样?有没有办法改善性能?

这是我的代码的相关部分:没有接收器的版本

//p is parameter with type p: Process[Task, Pixel]

def printToImage(img: BufferedImage)(pixel: Pixel): Unit = {
  img.setRGB(pixel.x, pixel.y, 1, 1, Array(pixel.rgb), 0, 0)
}
val image = getBlankImage(2000, 4000)
val result = p.runLog.run
result.foreach(printToImage(image))
Run Code Online (Sandbox Code Playgroud)

这需要大约7秒才能执行

带水槽的版本

//p is the same as before

def printToImage(img: BufferedImage)(pixel: Pixel): Unit = {
  img.setRGB(pixel.x, pixel.y, 1, 1, Array(pixel.rgb), 0, 0)
}

//I've found that way of doing sink in some tutorial
def getImageSink(img: BufferedImage): Sink[Task, Pixel] = {
  //I've tried here Task.delay and Task.now with the same results
  def printToImageTask(img: BufferedImage)(pixel: Pixel): Task[Unit] = Task.delay {
    printToImage(img)(pixel)
  }
  Process.constant(printToImageTask(img))
}



val image = getBlankImage(2000, 4000)
val result = p.to(getImageSink(image)).run.run
Run Code Online (Sandbox Code Playgroud)

这个需要33秒才能执行.由于这种显着的差异,我在这里完全感到困惑.

Eug*_*nev 7

在第二种情况下,您为每个像素分配任务,而不是直接调用printToImage,而是通过Task执行,而且它在调用链中的步骤更多.

我们经常使用scalaz-stream,但我坚信使用它来解决这类问题是一种过分的做法.在Process/Channel/Sink中运行的代码应该比简单的变量赋值/更新复杂得多.

我们使用Sinks将数据从流写入数据库(Cassandra),我们使用批处理,编写单个行的开销很高.Process/Sinks是超级方便的抽象,但适用于更高级别的工作流程.当写入for循环很容易时,我会建议写for循环.