为什么这个Scala代码会变慢?

时间:2012-02-23 02:24:37

标签: json performance scala

我正在运行以下Scala代码:

import scala.util.parsing.json._
import scala.io._

object Main {
        def jsonStringMap(str: String) =
                JSON.parseFull(str) match {
                        case Some(m: Map[_,_]) => m collect {
                                        // If this doesn't match, we'll just ignore the value
                                        case (k: String, v: String) => (k,v)
                                } toMap
                        case _ => Map[String,String]()
                }

        def main(args: Array[String]) {
                val fh = Source.fromFile("listings.txt")
                try {
                        fh.getLines map(jsonStringMap) foreach { v => println(v) }
                } finally {
                        fh.close
                }
        }
}

在我的机器上,http://sortable.com/blog/coding-challenge/的文件大约需要3分钟。我编写的等效Haskell和Ruby程序在4秒内完成。我做错了什么?

我在没有地图的情况下尝试了相同的代码(jsonStringMap)并且速度非常快,JSON解析器真的很慢吗?

默认的JSON解析器看起来确实很慢,但是我尝试了https://github.com/stevej/scala-json,虽然它降低到35秒,但仍然比Ruby慢得多。

我现在正在使用https://github.com/codahale/jerkson 甚至更快!我的程序现在只在我的数据上运行6秒,比Ruby慢3秒,这可能只是JVM的启动。

3 个答案:

答案 0 :(得分:8)

快速查看scala-user存档似乎表明没有人在scala标准库中使用JSON解析器进行认真的工作。

请参阅http://groups.google.com/group/scala-user/msg/fba208f2d3c08936

似乎解析器最终出现在标准库中,当时斯卡拉不太受欢迎,并且没有达到今天的预期。

答案 1 :(得分:3)

使用Jerkson。 Jerkson使用Jackson,它始终是JVM上最快的JSON库(特别是在流读/写时)大文档。

答案 2 :(得分:2)

使用my JSON library,我几乎可以即时解析这两个文件:

import com.github.seanparsons.jsonar._
import scala.io.Source
def parseLines[T](file: String, transform: (Iterator[String]) => T): T = {
  val log = Source.fromFile(file)
  val logLines = log.getLines()
  try { transform(logLines) } finally { log.close }
}
def parseFile(file: String) = parseLines(file, (iterator) => iterator.map(Parser.parse(_)).toList)
parseFile("products.txt"); parseFile("listings.txt")

然而,正如有人提到的那样,将整个事物解析为JSONArray而不是像这样有很多单独的行会更有用。