Skip to content

use gregorian days in RowBinary dates#318

Merged
ruslandoga merged 4 commits intomasterfrom
improve-dates
Apr 20, 2026
Merged

use gregorian days in RowBinary dates#318
ruslandoga merged 4 commits intomasterfrom
improve-dates

Conversation

@ruslandoga
Copy link
Copy Markdown
Collaborator

No description provided.

@ruslandoga ruslandoga changed the title Improve dates encoding use gregorian days in RowBinary dates encoding Apr 20, 2026
@ruslandoga ruslandoga changed the title use gregorian days in RowBinary dates encoding use gregorian days in RowBinary dates Apr 20, 2026
Comment thread bench/date_encode.exs
end
},
inputs: %{"now" => Date.utc_today()},
profile_after: true
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The main difference is tat with to_gregorian_days we call Calendar.ISO.date_to_iso_days/3 and with diff we call it twice, for our date and also for ~D[1970-01-01]

Comment thread bench/date_decode.exs
"add" => fn -> Enum.each(1..1_000_000, &Bench.add/1) end,
"gregorian" => fn -> Enum.each(1..1_000_000, &Bench.gregorian/1) end
},
profile_after: true
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Operating System: macOS
CPU Information: Apple M2
Number of Available Cores: 8
Available memory: 8 GB
Elixir 1.19.5
Erlang 28.3
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: none specified
Estimated total run time: 14 s
Excluding outliers: false

Benchmarking add ...
Benchmarking gregorian ...
Calculating statistics...
Formatting results...

Name                ips        average  deviation         median         99th %
gregorian         21.99       45.47 ms     ±2.85%       44.92 ms       48.38 ms
add               19.73       50.68 ms     ±3.35%       49.78 ms       58.45 ms

Comparison: 
gregorian         21.99
add               19.73 - 1.11x slower +5.21 ms

Profiling gregorian with eprof...

Profile results of #PID<0.198.0>
#                                                                  CALLS     %   TIME µS/CALL
Total                                                            1593882 100.0 988418    0.06
Benchee.Benchmark.BenchmarkConfig.from/1                               1  0.00      0    0.00
Benchee.Benchmark.BenchmarkConfig.__struct__/1                         1  0.00      0    0.00
:maps.try_next/2                                                      13  0.00      0    0.00
:maps.next/1                                                           1  0.00      0    0.00
:maps.iterator/2                                                       1  0.00      0    0.00
:maps.iterator/1                                                       1  0.00      0    0.00
:maps.fold/3                                                           1  0.00      0    0.00
Map.take/2                                                             1  0.00      0    0.00
:erts_internal.map_next/3                                              1  0.00      0    0.00
anonymous fn/0 in :elixir_compiler_2.__FILE__/1                        1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_before_scenario/2                          1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_before_function/2                          4  0.00      0    0.00
Benchee.Benchmark.Hooks.run_before_each/2                              1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_after_scenario/2                           1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_after_each/3                               1  0.00      0    0.00
Benchee.Benchmark.Runner.main_function/2                               1  0.00      0    0.00
Kernel.validate_struct!/3                                              1  0.00      0    0.00
Kernel.struct!/2                                                       1  0.00      0    0.00
anonymous fn/4 in Enum.reduce/3                                       13  0.00      0    0.00
Enum.reduce/3                                                          1  0.00      0    0.00
Enum.each/2                                                            1  0.00      0    0.00
anonymous fn/2 in Benchee.Benchmark.BenchmarkConfig.__struct__/1      13  0.00      1    0.08
:erlang.apply/2                                                        1  0.00      1    1.00
:maps.fold_1/4                                                        14  0.00      1    0.07
:maps.from_list/1                                                      1  0.00      1    1.00
Benchee.Benchmark.Runner.run_once/2                                    1  0.00      1    1.00
Map.take/3                                                            14  0.00      3    0.21
anonymous fn/2 in Benchee.Profile.run/4                                1  0.00      5    5.00
Benchee.Benchmark.Runner.collect_return_value/2                        1  0.00      6    6.00
Date.from_gregorian_days/1                                       1000000  3.63  35862    0.04
Date.from_gregorian_days/2                                       1000000  3.66  36164    0.04
Bench.gregorian/1                                                1000000  3.73  36839    0.04
Calendar.ISO.leap_year?/1                                        1000000  4.10  40554    0.04
Calendar.ISO.year_day_to_year_date/2                             1000000  4.38  43294    0.04
Enum.reduce_range/5                                               500001  5.43  53622    0.11
Date.from_iso_days/2                                             1000000  7.59  75061    0.08
anonymous fn/3 in Enum.each/2                                    1000000  7.64  75475    0.08
Calendar.ISO.days_to_year/1                                      1000000 11.24 111101    0.11
Calendar.ISO.days_in_previous_years/1                            3219367 12.09 119522    0.04
Calendar.ISO.date_from_iso_days/1                                1000000 14.86 146892    0.15
Calendar.ISO.days_to_year/3                                      3219367 21.65 214013    0.07

Profile done over 41 matching functions

Profiling add with eprof...

Profile results of #PID<0.200.0>
#                                                                  CALLS     %   TIME µS/CALL
Total                                                            1593882 100.0 100653    0.06
Benchee.Benchmark.BenchmarkConfig.__struct__/1                         1  0.00      0    0.00
:maps.try_next/2                                                      13  0.00      0    0.00
:maps.next/1                                                           1  0.00      0    0.00
:maps.iterator/2                                                       1  0.00      0    0.00
:maps.iterator/1                                                       1  0.00      0    0.00
:maps.fold/3                                                           1  0.00      0    0.00
:maps.from_list/1                                                      1  0.00      0    0.00
:erts_internal.map_next/3                                              1  0.00      0    0.00
anonymous fn/0 in :elixir_compiler_2.__FILE__/1                        1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_before_function/2                          4  0.00      0    0.00
Benchee.Benchmark.Hooks.run_before_each/2                              1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_after_scenario/2                           1  0.00      0    0.00
Benchee.Benchmark.Hooks.run_after_each/3                               1  0.00      0    0.00
Benchee.Benchmark.Runner.run_once/2                                    1  0.00      0    0.00
Benchee.Benchmark.Runner.main_function/2                               1  0.00      0    0.00
anonymous fn/2 in Benchee.Profile.run/4                                1  0.00      0    0.00
Kernel.validate_struct!/3                                              1  0.00      0    0.00
Kernel.struct!/2                                                       1  0.00      0    0.00
anonymous fn/4 in Enum.reduce/3                                       13  0.00      0    0.00
Enum.reduce/3                                                          1  0.00      0    0.00
anonymous fn/2 in Benchee.Benchmark.BenchmarkConfig.__struct__/1      13  0.00      1    0.08
Benchee.Benchmark.BenchmarkConfig.from/1                               1  0.00      1    1.00
:erlang.apply/2                                                        1  0.00      1    1.00
:maps.fold_1/4                                                        14  0.00      1    0.07
Benchee.Benchmark.Hooks.run_before_scenario/2                          1  0.00      1    1.00
Benchee.Benchmark.Runner.collect_return_value/2                        1  0.00      1    1.00
Enum.each/2                                                            1  0.00      1    1.00
Map.take/2                                                             1  0.00      4    4.00
Map.take/3                                                            14  0.00      5    0.36
Calendar.ISO.date_to_iso_days/3                                  1000000  3.46  34809    0.03
Bench.add/1                                                      1000000  3.60  36192    0.04
Calendar.ISO.leap_year?/1                                        1000000  4.01  40324    0.04
Calendar.ISO.year_day_to_year_date/2                             1000000  4.32  43479    0.04
Enum.reduce_range/5                                               500001  5.18  52123    0.10
anonymous fn/3 in Enum.each/2                                    1000000  7.34  73918    0.07
Date.add/2                                                       1000000  7.38  74252    0.07
Calendar.ISO.shift_days/2                                        1000000  7.97  80270    0.08
Calendar.ISO.days_to_year/1                                      1000000 10.86 109303    0.11
Calendar.ISO.days_in_previous_years/1                            3219367 12.02 120962    0.04
Calendar.ISO.date_from_iso_days/1                                1000000 14.09 141822    0.14
Calendar.ISO.days_to_year/3                                      3219367 19.78 199066    0.06

Profile done over 41 matching functions

Copy link
Copy Markdown
Collaborator Author

@ruslandoga ruslandoga Apr 20, 2026

Choose a reason for hiding this comment

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

These are pretty much the same, but Date.add/2 still has to Calendar.ISO.date_to_iso_days/3 ~D[1970-01-01] and we skip it in the gregorian version.

@ruslandoga ruslandoga merged commit a552ff7 into master Apr 20, 2026
6 checks passed
@ruslandoga ruslandoga deleted the improve-dates branch April 20, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant