Skip to content

Commit

Permalink
Fix performance regression in JSON serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Joni Freeman committed Oct 19, 2011
1 parent 1ffac23 commit e3cc1e1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
27 changes: 19 additions & 8 deletions core/json/src/main/scala/net/liftweb/json/Meta.scala
Expand Up @@ -218,6 +218,9 @@ private[json] object Meta {
classOf[java.lang.Short], classOf[Date], classOf[Symbol], classOf[JValue],
classOf[JObject], classOf[JArray]).map((_, ())))

private val primaryConstructors = new Memo[Class[_], List[(String, Type)]]
private val declaredFields = new Memo[(Class[_], String), Boolean]

def constructors(t: Type, names: ParameterNameReader, context: Option[Context]): List[(JConstructor[_], List[(String, Type)])] =
rawClassOf(t).getDeclaredConstructors.map(c => (c, constructorArgs(t, c, names, context))).toList

Expand Down Expand Up @@ -255,9 +258,13 @@ private[json] object Meta {
}

def primaryConstructorArgs(c: Class[_])(implicit formats: Formats) = {
val ord = Ordering[Int].on[JConstructor[_]](_.getParameterTypes.size)
val primary = c.getDeclaredConstructors.max(ord)
constructorArgs(c, primary, formats.parameterNameReader, None)
def findMostComprehensive(c: Class[_]): List[(String, Type)] = {
val ord = Ordering[Int].on[JConstructor[_]](_.getParameterTypes.size)
val primary = c.getDeclaredConstructors.max(ord)
constructorArgs(c, primary, formats.parameterNameReader, None)
}

primaryConstructors.memoize(c, findMostComprehensive(_))
}

def typeParameters(t: Type, k: Kind, context: Context): List[Class[_]] = {
Expand Down Expand Up @@ -346,11 +353,15 @@ private[json] object Meta {
else findField(clazz.getSuperclass, name)
}

def hasDeclaredField(clazz: Class[_], name: String): Boolean = try {
clazz.getDeclaredField(name)
true
} catch {
case e: NoSuchFieldException => false
def hasDeclaredField(clazz: Class[_], name: String): Boolean = {
def declaredField = try {
clazz.getDeclaredField(name)
true
} catch {
case e: NoSuchFieldException => false
}

declaredFields.memoize((clazz, name), _ => declaredField)
}

def mkJavaArray(x: Any, componentType: Class[_]) = {
Expand Down
Expand Up @@ -138,6 +138,11 @@ object SerializationExamples extends Specification {

object ShortTypeHintExamples extends TypeHintExamples {
implicit val formats = Serialization.formats(ShortTypeHints(classOf[Fish] :: classOf[Dog] :: Nil))

// "Deserialization succeeds even if jsonClass is not the first field" in {
// val ser = """{"animals":[],"pet":{"name":"pluto","jsonClass":"Dog"}}"""
// Serialization.read[Animals](ser) mustEqual Animals(Nil, Dog("pluto"))
// }
}

object FullTypeHintExamples extends TypeHintExamples {
Expand Down

0 comments on commit e3cc1e1

Please sign in to comment.