2012-02-23 21 views
7

estoy ejecutando el siguiente código Scala:¿Por qué este código de Scala es lento?

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 
       } 
     } 
} 

En mi máquina que toma ~ 3 minutos en el archivo desde http://sortable.com/blog/coding-challenge/. Los programas equivalentes de Haskell y Ruby que escribí toman menos de 4 segundos. ¿Qué estoy haciendo mal?

Probé el mismo código sin el mapa (jsonStringMap) y fue bastante rápido, ¿el analizador JSON es realmente lento?

Parece probable que el analizador JSON predeterminado sea realmente lento, sin embargo, probé https://github.com/stevej/scala-json y aunque eso lo reduce a 35 segundos, eso es mucho más lento que Ruby.

Ahora estoy usando https://github.com/codahale/jerkson que es incluso más rápido! Mi programa ahora se ejecuta en solo 6 segundos en mis datos, solo 3 segundos más lento que Ruby, que probablemente sea solo el arranque de JVM.

+0

tal vez un mejor ajuste para codereview.stackexchange.com – Nettogrof

+0

Offhand, parece que está analizando cada línea de forma independiente. ¿Intentó invocar el analizador una vez para todo el documento JSON? –

+0

@ChrisShain Podría convertir todo el archivo en un documento JSON, pero (a) No veo cómo eso sería más rápido, porque no puede transmitir las líneas incluso desde el archivo, pero tendría que hacerlo todo de una vez (b) ¿por qué hacer lo mismo que está haciendo en Ruby es mucho más rápido? – singpolyma

Respuesta

8

Un vistazo rápido al archivo scala-user parece indicar que nadie está trabajando seriamente con el analizador JSON en la biblioteca estándar scala.

Ver http://groups.google.com/group/scala-user/msg/fba208f2d3c08936

Parece que el analizador terminado en la biblioteca estándar en un momento en Scala fue menor en el centro de atención y no tenía las expectativas que tiene hoy.

2

Usando my JSON library, consigo un análisis sintáctico casi instantánea de los dos archivos:

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") 

Sin embargo, como alguien ha mencionado, sería más útil que acaba de analizar todo el asunto como una JSONArray en lugar de tener un montón de individuo líneas como esto lo hace.

3

Use Jerkson. Jerkson usa Jackson, que es siempre la biblioteca JSON más rápida en JVM (especialmente cuando lee o escribe en tiempo real) documentos grandes.

+0

De acuerdo con el enlace, el proyecto ha sido abandonado. – null

Cuestiones relacionadas