Skip to content

Optimize UTC-offset adjustment in Calendar.ISO parsing - #15919

Merged
josevalim merged 1 commit into
elixir-lang:mainfrom
preciz:perf/calendar-joffe-5
Sep 20, 2026
Merged

josevalim merged 1 commit into
elixir-lang:mainfrom
preciz:perf/calendar-joffe-5

Conversation

@preciz

@preciz preciz commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Assisted-by: Codex:GPT-6

~1.3x faster and uses less memory.

Normalize nonzero UTC offsets directly in seconds and reuse seconds_to_time/1, avoiding intermediate day-fraction conversions while preserving parsed microseconds and precision.

Bench:

# Run with: elixir bench.exs
Mix.install([:benchee])

path = "lib/elixir/lib/calendar/iso.ex"

for {ref, module} <- [{"main", Old}, {"HEAD", New}] do
  {source, 0} = System.cmd("git", ["show", "#{ref}:#{path}"], cd: __DIR__)

  source
  |> String.replace("defmodule Calendar.ISO do", "defmodule #{inspect(module)} do")
  |> Code.compile_string(path)
end

Benchee.run(
  %{"main" => &Old.parse_utc_datetime/1, "HEAD" => &New.parse_utc_datetime/1},
  inputs: %{
    "positive, same day" => "2024-03-01T12:34:56.123456+02:30",
    "positive, previous day" => "2024-03-01T00:15:23.123456+02:30",
    "negative, same day" => "2024-03-01T12:34:56.123456-02:30",
    "negative, next day" => "2024-12-31T23:45:01.123456-02:30"
  },
  pre_check: :all_same,
  warmup: 1,
  time: 3,
  memory_time: 1
)

Results:

Operating System: Linux
CPU Information: AMD Ryzen 7 8845HS w
Number of Available Cores: 16
Available memory: 54.72 GB
Elixir 1.21.0-dev
Erlang 29.0.5
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 1 s
time: 3 s
memory time: 1 s
reduction time: 0 ns
parallel: 1
inputs: negative, next day, negative, same day, positive, previous day, positive, same day
Estimated total run time: 40 s
Excluding outliers: false

##### With input negative, next day #####
Name           ips        average  deviation         median         99th %
HEAD        3.90 M      256.23 ns  ±2078.02%         230 ns         371 ns
main        3.12 M      320.46 ns  ±1322.08%         291 ns         441 ns

Comparison: 
HEAD        3.90 M
main        3.12 M - 1.25x slower +64.24 ns

Memory usage statistics:

Name    Memory usage
HEAD           616 B
main           792 B - 1.29x memory usage +176 B

**All measurements for memory usage were the same**

##### With input negative, same day #####
Name           ips        average  deviation         median         99th %
HEAD        4.54 M      220.15 ns  ±2260.04%         191 ns         331 ns
main        3.29 M      303.67 ns  ±1560.26%         271 ns         421 ns

Comparison: 
HEAD        4.54 M
main        3.29 M - 1.38x slower +83.52 ns

Memory usage statistics:

Name    Memory usage
HEAD           616 B
main           792 B - 1.29x memory usage +176 B

**All measurements for memory usage were the same**

##### With input positive, previous day #####
Name           ips        average  deviation         median         99th %
HEAD        3.96 M      252.36 ns  ±2284.39%         230 ns         370 ns
main        3.02 M      331.67 ns  ±1502.95%         301 ns         451 ns

Comparison: 
HEAD        3.96 M
main        3.02 M - 1.31x slower +79.31 ns

Memory usage statistics:

Name    Memory usage
HEAD           616 B
main           792 B - 1.29x memory usage +176 B

**All measurements for memory usage were the same**

##### With input positive, same day #####
Name           ips        average  deviation         median         99th %
HEAD        4.68 M      213.69 ns  ±2346.88%         190 ns         321 ns
main        3.17 M      315.05 ns  ±1518.93%         281 ns         441 ns

Comparison: 
HEAD        4.68 M
main        3.17 M - 1.47x slower +101.36 ns

Memory usage statistics:

Name    Memory usage
HEAD           616 B
main           792 B - 1.29x memory usage +176 B

**All measurements for memory usage were the same**

Normalize nonzero UTC offsets directly in seconds and reuse seconds_to_time/1, avoiding intermediate day-fraction conversions while preserving parsed microseconds and precision.

Assisted-by: Codex:GPT-6
@josevalim
josevalim merged commit b25d347 into elixir-lang:main Sep 20, 2026
12 of 15 checks passed
@josevalim

Copy link
Copy Markdown
Member

💚 💙 💜 💛 ❤️

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.

2 participants