Skip to content

Commit

Permalink
Merge 8681711 into 8e7ad4b
Browse files Browse the repository at this point in the history
  • Loading branch information
NickNeck committed May 5, 2020
2 parents 8e7ad4b + 8681711 commit d56ca43
Show file tree
Hide file tree
Showing 16 changed files with 1,211 additions and 825 deletions.
2 changes: 1 addition & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test,scripts}/**/*.{ex,exs}"],
import_deps: [:stream_data, :nimble_parsec, :plug],
import_deps: [:stream_data, :nimble_parsec, :plug, :benchee_dsl],
locals_without_parens: [prove: 1, prove: 2]
]
689 changes: 213 additions & 476 deletions bench/README.md

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions bench/benchee_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
alias BencheeDsl.Benchmark
alias TimeZoneInfo.{DataStore, IanaParser, Transformer}

Application.ensure_all_started(:tzdata)

Code.require_file("bench/data.exs")
Code.require_file("test/support/time_zone_info/data_store/server.exs")

path = "test/fixtures/iana/2019c"
files = ~w(africa antarctica asia australasia etcetera europe northamerica southamerica)

time_zone_info_data =
with {:ok, data} <- IanaParser.parse(path, files) do
Transformer.transform(data, "2019c", lookahead: 5)
end

DataStore.PersistentTerm.put(time_zone_info_data)
DataStore.ErlangTermStorage.put(time_zone_info_data)
DataStore.Server.put(time_zone_info_data)

BencheeDsl.config(
before_each_benchmark: fn benchmark ->
file_name =
case benchmark.module do
TimeZoneDatabaseBench -> "README.md"
module -> Macro.underscore(module) <> ".md"
end

file = Path.join(benchmark.dir, file_name)

Benchmark.update(benchmark, [:config, :formatters], fn formatters ->
formatter = {
Benchee.Formatters.Markdown,
file: file, description: benchmark.description
}

[formatter | formatters]
end)
end
)

BencheeDsl.run(
time: 10,
memory_time: 2
)
48 changes: 48 additions & 0 deletions bench/data.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule Data do
@moduledoc false

alias TimeZoneInfo.DataStore

def inputs do
data = Code.eval_file("bench/data/333_ok_gap_ambiguous.exs") |> elem(0)

%{
world_ok: Map.get(data, :ok),
world_gap: Map.get(data, :gap),
world_ambiguous: Map.get(data, :ambiguous),
world_last_year: last_year(),
berlin_gap_2020: berlin_2020(:gap),
berlin_ambiguous_2020: berlin_2020(:ambiguous),
berlin_ok_2020: berlin_2020(:ok)
}
end

defp last_year do
Application.put_env(:time_zone_info, :data_store, DataStore.ErlangTermStorage)
seconds_per_year = 31_622_400
now = NaiveDateTime.utc_now()

Enum.map(0..333, fn _ ->
time_zone = Enum.random(TimeZoneInfo.time_zones())
datetime = NaiveDateTime.add(now, :rand.uniform(seconds_per_year) * -1)
{datetime, time_zone}
end)
end

defp berlin_2020(mode) do
datetime =
case mode do
:gap ->
~N[2020-03-29 02:00:01]

:ambiguous ->
~N[2020-10-25 02:00:01]
:ok ->
~N[2020-06-25 00:00:00]
end

Enum.map(0..333, fn index ->
{NaiveDateTime.add(datetime, index), "Europe/Berlin"}
end)
end
end
10 changes: 0 additions & 10 deletions bench/run.exs

This file was deleted.

100 changes: 0 additions & 100 deletions bench/scripts/gen_data.exs

This file was deleted.

65 changes: 65 additions & 0 deletions bench/stores_bench.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule StoresBench do
use BencheeDsl.Benchmark

alias TimeZoneInfo.DataStore

@title "Benchmark: TimeZoneDatabase"

@description """
This benchmark compares the different `DataStores` available in
`TimeZoneInfo`.
The `TimeZoneInfo` will be tested in three different configurations.
Each version uses a different strategy to keep the data available.
- `time_zone_info_pst` is using
[`:persistent_term`](https://erlang.org/doc/man/persistent_term.html)
- `time_zone_info_ets` is using `:ets`
[(Erlang Term Storage)](https://erlang.org/doc/man/ets.html)
- `time_zone_info_map` is using a `GenServer` with a `Map` as state. This
version isn't an available configuration in `TimeZoneInfo`. The
`GenServer` version is otherwise only used in the tests.
The inputs for every benchmark run:
- **world_ok:** 333 `(datetime, time_zone)` arguments that are resulting in a
`:ok` return value.
- **world_gap:** 333 `(datetime, time_zone)` arguments that are resulting in a
`:gap` return tuple.
- **world_ambiguous:** 333 `(datetime, time_zone)` arguments that are resulting in
a `:ambiguous` return tuple.
- **world_last_year:** 333 `(datetime, time_zone)` arguments with random time zone
and a date time from now to one year in the past. The data is calculated
once for all test candidates.
- **berlin_gap_2020**: 333 gaps in the time zone `Europe/Berlin` in 2020.
- **berlin_ambiguous_2020**: 333 ambiguous date time in the time zone
`Europe/Berlin` in 2020.
The inputs **ok**, **gap**, and **ambiguous** containing random time zones
and date times between 1900 and 2050.
"""

inputs Data.inputs()

job time_zone_info_ets(data) do
Application.put_env(:time_zone_info, :data_store, DataStore.ErlangTermStorage)

Enum.each(data, fn {datetime, time_zone} ->
TimeZoneInfo.TimeZoneDatabase.time_zone_periods_from_wall_datetime(datetime, time_zone)
end)
end

job time_zone_info_pst(data) do
Application.put_env(:time_zone_info, :data_store, DataStore.PersistentTerm)

Enum.each(data, fn {datetime, time_zone} ->
TimeZoneInfo.TimeZoneDatabase.time_zone_periods_from_wall_datetime(datetime, time_zone)
end)
end

job time_zone_info_map(data) do
Application.put_env(:time_zone_info, :data_store, DataStore.Server)

Enum.each(data, fn {datetime, time_zone} ->
TimeZoneInfo.TimeZoneDatabase.time_zone_periods_from_wall_datetime(datetime, time_zone)
end)
end
end

0 comments on commit d56ca43

Please sign in to comment.