Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize JSON parsing of unions #2741

Merged
merged 1 commit into from
Jun 4, 2016
Merged

Conversation

asterite
Copy link
Member

@asterite asterite commented Jun 3, 2016

This includes two things:

  1. One can now pass Int32 | Nil to JSON.mapping, instead of having to use the more verbose {type: Int32, nilable: true}.
  2. Optimized parsing for Union where primitive types are involved

I did a small benchmark for this:

time = Time.now
100_000.times do
  Float64.from_json(%(1))
  String.from_json(%("hello"))
  Bool.from_json(%(false))
  Array(Int32).from_json(%([1, 2, 3]))
end
puts Time.now - time

time = Time.now
100_000.times do
  Union(Float64, String, Bool, Array(Int32)).from_json(%(1))
  Union(Float64, String, Bool, Array(Int32)).from_json(%("hello"))
  Union(Float64, String, Bool, Array(Int32)).from_json(%(false))
  Union(Float64, String, Bool, Array(Int32)).from_json(%([1, 2, 3]))
end
puts Time.now - time

Before the optimization:

00:00:00.4988820
00:00:03.9123560

After the optimization:

00:00:00.4549360
00:00:00.4819530

So I'd say these optimizations, even though they make the code just a bit longer, are very good :-)

Point 1 means we can now do:

class Foo
  JSON.mapping({
    x: Int32 | Nil,
  })
end

instead of:

class Foo
  JSON.mapping({
    x: {type: Int32, nilable: true},
  })
end

That's definitely better. But, wouldn't it be nice, since this notation is used in other places, to be able to just write:

class Foo
  JSON.mapping({
    x: Int32?,
  })
end

I understand that it's simpler not adding parser support for Int32? outside the type grammar, but one of Crystal's philosophy is pragmatism and developer happiness. I believe parsing T? as Union(T, ::Nil) everywhere will make things less verbose and more consistent. I'll send that in a separate PR and later we can see if we merge it.

@asterite asterite force-pushed the feature/optimize_json_parse_union branch from f43f25a to d51fc00 Compare June 4, 2016 00:39
@asterite asterite merged commit f0df169 into master Jun 4, 2016
@asterite asterite deleted the feature/optimize_json_parse_union branch June 4, 2016 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant