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

Implement JSON.Encoder for Calendar types #14061

Merged
merged 1 commit into from
Dec 11, 2024
Merged

Implement JSON.Encoder for Calendar types #14061

merged 1 commit into from
Dec 11, 2024

Conversation

josevalim
Copy link
Member

Should be backported if accepted.

@sorentwo
Copy link
Contributor

Really pleased to see this. It was the only barrier to a clean transition from Jason for my benchmarking purposes.

@josevalim
Copy link
Member Author

Can you manually add it to your benches for now and let us know the numbers? :)

@sorentwo
Copy link
Contributor

Can you manually add it to your benches for now and let us know the numbers? :)

Sure thing. After applying the patch the test suites all pass, and here's the benchmark:

args = %{
  a: 1,
  b: "value",
  c: true,
  d: "baz",
  e: [1],
  f: %{f1: 123},
  g: [%{g1: "bat"}],
  h: "abc-123",
  i: ["abc-123"],
  j: ["foo", "bar"],
  k: [:a, :b],
  l: Date.utc_today(),
  m: Time.utc_now(),
  n: DateTime.utc_now(),
  o: NaiveDateTime.utc_now()
}

recode = fn encoder ->
  args
  |> encoder.encode!()
  |> encoder.decode!()
end

Benchee.run(%{"Encode/Decode" => recode}, inputs: Map.new([Jason, JSON], &{&1, &1}))

And here are the results:

Operating System: macOS
CPU Information: Apple M3 Pro
Number of Available Cores: 12
Available memory: 36 GB
Elixir 1.18.0-dev
Erlang 27.0
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: Elixir.JSON, Elixir.Jason
Estimated total run time: 14 s

Benchmarking Encode/Decode with input Elixir.JSON ...
Benchmarking Encode/Decode with input Elixir.Jason ...
Calculating statistics...
Formatting results...

##### With input Elixir.JSON #####
Name                    ips        average  deviation         median         99th %
Encode/Decode      175.89 K        5.69 μs   ±219.43%        4.67 μs       15.88 μs

##### With input Elixir.Jason #####
Name                    ips        average  deviation         median         99th %
Encode/Decode      150.05 K        6.66 μs   ±169.02%        5.08 μs       21.13 μs

It's a great improvement for a synthetic, small, but type exhaustive benchmark.

Copy link
Contributor

@sabiwara sabiwara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@josevalim josevalim merged commit 8a0cd66 into main Dec 11, 2024
18 checks passed
@josevalim josevalim deleted the jv-calendar-json branch December 11, 2024 23:37
@josevalim
Copy link
Member Author

💚 💙 💜 💛 ❤️

@@ -150,6 +150,12 @@ defimpl JSON.Encoder, for: Map do
end
end

defimpl JSON.Encoder, for: [Date, Time, NaiveDateTime, DateTime] do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should Duration also be included?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked myself the same and, honestly, I am not sure. We could easily use the ISO representation, but I am not sure how widespread it is, it is definitely less common than the datetime ones.

Copy link

@Wigny Wigny Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, in the JS world it is common to serialise duration as ISO strings when parsing it to JSON (see Temporal.Duration.toJSON or dayjs.duration). As the string format chose in serialization is just a convention, I hopped ISO strings was a good enough format to be used as default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants