Skip to content

Commit 82e2eb3

Browse files
authored
Fix benchmarks (#707)
* pull in JSON and HTML formatters, set them up correctly * add numbers to preserve order * remove a warning * use Enum.each to avoid allocating data
1 parent b75665a commit 82e2eb3

File tree

8 files changed

+57
-48
lines changed

8 files changed

+57
-48
lines changed

bench/scripts/macro/all_bench.exs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,9 @@ jobs = %{
3535
"MyXQL Repo.all/2" => fn -> Ecto.Bench.MyXQLRepo.all(User, limit: limit) end
3636
}
3737

38-
path = System.get_env("BENCHMARKS_OUTPUT_PATH") || "bench/results"
39-
file = Path.join(path, "all.json")
40-
4138
Benchee.run(
4239
jobs,
43-
formatters: [Benchee.Formatters.Console],
44-
formatter_options: [json: [file: file]],
40+
formatters: Ecto.Bench.Helper.formatters("all"),
4541
time: 10,
4642
after_each: fn results ->
4743
^limit = length(results)

bench/scripts/macro/insert_bench.exs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,10 @@ jobs = %{
2929
"MyXQL Insert" => fn entry -> Ecto.Bench.MyXQLRepo.insert!(entry) end
3030
}
3131

32-
path = System.get_env("BENCHMARKS_OUTPUT_PATH") || "bench/results"
33-
file = Path.join(path, "insert.json")
34-
3532
Benchee.run(
3633
jobs,
3734
inputs: inputs,
38-
formatters: [Benchee.Formatters.Console],
39-
formatter_options: [json: [file: file]]
35+
formatters: Ecto.Bench.Helper.formatters("insert")
4036
)
4137

4238
# Clean inserted data

bench/scripts/micro/load_bench.exs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,34 @@ Code.require_file("../../support/setup.exs", __DIR__)
2222
alias Ecto.Bench.User
2323

2424
inputs = %{
25-
"Small 1 Thousand" =>
26-
1..1_000 |> Enum.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
27-
"Medium 100 Thousand" =>
28-
1..100_000 |> Enum.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
29-
"Big 1 Million" =>
30-
1..1_000_000 |> Enum.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
31-
"Time attr" =>
32-
1..100_000 |> Enum.map(fn _ -> %{name: "Alice", time_attr: ~T[21:25:04.361140]} end),
33-
"Date attr" => 1..100_000 |> Enum.map(fn _ -> %{name: "Alice", date_attr: ~D[2018-06-20]} end),
34-
"NaiveDateTime attr" =>
25+
"1. Small 1 Thousand" =>
26+
1..1_000 |> Stream.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
27+
"2. Medium 100 Thousand" =>
28+
1..100_000 |> Stream.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
29+
"3. Big 1 Million" =>
30+
1..1_000_000 |> Stream.map(fn _ -> %{name: "Alice", email: "email@email.com"} end),
31+
"4. Time attr" =>
32+
1..100_000 |> Stream.map(fn _ -> %{name: "Alice", time_attr: ~T[21:25:04.361140]} end),
33+
"5. Date attr" =>
34+
1..100_000 |> Stream.map(fn _ -> %{name: "Alice", date_attr: ~D[2018-06-20]} end),
35+
"6. NaiveDateTime attr" =>
3536
1..100_000
36-
|> Enum.map(fn _ -> %{name: "Alice", naive_datetime_attr: ~N[2019-06-20 21:32:07.424178]} end),
37-
"UUID attr" =>
37+
|> Stream.map(fn _ ->
38+
%{name: "Alice", naive_datetime_attr: ~N[2019-06-20 21:32:07.424178]}
39+
end),
40+
"7. UUID attr" =>
3841
1..100_000
39-
|> Enum.map(fn _ -> %{name: "Alice", uuid: Ecto.UUID.bingenerate()} end)
42+
|> Stream.map(fn _ -> %{name: "Alice", uuid: Ecto.UUID.bingenerate()} end)
4043
}
4144

4245
jobs = %{
43-
"Pg Loader" => fn data -> Enum.map(data, &Ecto.Bench.PgRepo.load(User, &1)) end,
44-
"MyXQL Loader" => fn data -> Enum.map(data, &Ecto.Bench.MyXQLRepo.load(User, &1)) end
46+
"Control" => fn stream -> Enum.each(stream, fn _data -> true end) end,
47+
"Pg Loader" => fn stream -> Enum.each(stream, &Ecto.Bench.PgRepo.load(User, &1)) end,
48+
"MyXQL Loader" => fn stream -> Enum.each(stream, &Ecto.Bench.MyXQLRepo.load(User, &1)) end
4549
}
4650

47-
path = System.get_env("BENCHMARKS_OUTPUT_PATH") || "bench/results"
48-
file = Path.join(path, "load.json")
49-
5051
Benchee.run(
5152
jobs,
5253
inputs: inputs,
53-
formatters: [Benchee.Formatters.Console],
54-
formatter_options: [json: [file: file]]
54+
formatters: Ecto.Bench.Helper.formatters("load")
5555
)

bench/scripts/micro/to_sql_bench.exs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@ import Ecto.Query
2525
alias Ecto.Bench.{User, Game}
2626

2727
inputs = %{
28-
"Ordinary Select All" => {:all, from(User)},
29-
"Ordinary Delete All" => {:delete_all, from(User)},
30-
"Ordinary Update All" => {:update_all, from(User, update: [set: [name: "Thor"]])},
31-
"Ordinary Where" => {:all, from(User, where: [name: "Thanos", email: "blah@blah"])},
32-
"Fetch First Registry" => {:all, first(User)},
33-
"Fetch Last Registry" => {:all, last(User)},
34-
"Ordinary Order By" => {:all, order_by(User, desc: :name)},
35-
"Complex Query 2 Joins" =>
28+
"1. Ordinary Select All" => {:all, from(User)},
29+
"2. Ordinary Delete All" => {:delete_all, from(User)},
30+
"3. Ordinary Update All" => {:update_all, from(User, update: [set: [name: "Thor"]])},
31+
"4. Ordinary Where" => {:all, from(User, where: [name: "Thanos", email: "blah@blah"])},
32+
"5. Fetch First Registry" => {:all, first(User)},
33+
"6. Fetch Last Registry" => {:all, last(User)},
34+
"7. Ordinary Order By" => {:all, order_by(User, desc: :name)},
35+
"8. Complex Query 2 Joins" =>
3636
{:all,
3737
from(User, where: [name: "Thanos"])
3838
|> join(:left, [u], ux in User, on: u.id == ux.id)
3939
|> join(:right, [j], uj in User, on: j.id == 1 and j.email == "email@email")
4040
|> select([u, ux], {u.name, ux.email})},
41-
"Complex Query 4 Joins" =>
41+
"9. Complex Query 4 Joins" =>
4242
{:all,
4343
from(User)
4444
|> join(:left, [u], g in Game, on: g.name == u.name)
4545
|> join(:right, [g], u in User, on: g.id == 1 and u.email == "email@email")
46-
|> join(:inner, [u], g in fragment("SELECT * from games where game.id = ?", u.id))
47-
|> join(:left, [g], u in fragment("SELECT * from users = ?", g.id))
46+
|> join(:inner, [u], g in fragment("SELECT * from games where game.id = ?", u.id), on: true)
47+
|> join(:left, [g], u in fragment("SELECT * from users = ?", g.id), on: true)
4848
|> select([u, g], {u.name, g.price})}
4949
}
5050

@@ -53,12 +53,8 @@ jobs = %{
5353
"MyXQL Query Builder" => fn {type, query} -> Ecto.Bench.MyXQLRepo.to_sql(type, query) end
5454
}
5555

56-
path = System.get_env("BENCHMARKS_OUTPUT_PATH") || "bench/results"
57-
file = Path.join(path, "to_sql.json")
58-
5956
Benchee.run(
6057
jobs,
6158
inputs: inputs,
62-
formatters: [Benchee.Formatters.Console],
63-
formatter_options: [json: [file: file]]
59+
formatters: Ecto.Bench.Helper.formatters("to_sql")
6460
)

bench/support/helper.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
defmodule Ecto.Bench.Helper do
2+
def report_dir, do: System.get_env("BENCHMARKS_OUTPUT_PATH") || "bench/results"
3+
4+
def formatters(test_name) do
5+
timestamp = DateTime.now!("Etc/UTC") |> DateTime.to_unix(:second)
6+
file = Path.join(report_dir(), "#{timestamp}_#{test_name}")
7+
[
8+
Benchee.Formatters.Console,
9+
{Benchee.Formatters.JSON, file: "#{file}.json"},
10+
{Benchee.Formatters.HTML, file: "#{file}.html", auto_open: false}
11+
]
12+
end
13+
end

bench/support/setup.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
Code.require_file("repo.exs", __DIR__)
22
Code.require_file("migrations.exs", __DIR__)
33
Code.require_file("schemas.exs", __DIR__)
4+
Code.require_file("helper.exs", __DIR__)
5+
6+
File.mkdir_p(Ecto.Bench.Helper.report_dir())
47

58
alias Ecto.Bench.{PgRepo, MyXQLRepo, CreateUser}
9+
alias Ecto.Bench.{PgRepo, CreateUser}
610

711
{:ok, _} = Ecto.Adapters.Postgres.ensure_all_started(PgRepo.config(), :temporary)
812
{:ok, _} = Ecto.Adapters.MyXQL.ensure_all_started(MyXQLRepo.config(), :temporary)

mix.exs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ defmodule EctoSQL.MixProject do
6262
tds_dep(),
6363

6464
# Bring something in for JSON during tests
65-
{:jason, ">= 0.0.0", only: [:test, :docs]},
65+
{:jason, "~> 1.0", only: [:test, :bench, :docs]},
6666

6767
# Docs
6868
{:ex_doc, "~> 0.21", only: :docs},
6969

7070
# Benchmarks
71-
{:benchee, "~> 1.0", only: :bench}
71+
{:benchee, "~> 1.0", only: :bench},
72+
{:benchee_html, "~> 1.0", only: :bench},
73+
{:benchee_json, "~> 1.0", only: :bench}
7274
]
7375
end
7476

mix.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
%{
22
"benchee": {:hex, :benchee, "1.2.0", "afd2f0caec06ce3a70d9c91c514c0b58114636db9d83c2dc6bfd416656618353", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "ee729e53217898b8fd30aaad3cce61973dab61574ae6f48229fe7ff42d5e4457"},
3+
"benchee_html": {:hex, :benchee_html, "1.0.1", "1e247c0886c3fdb0d3f4b184b653a8d6fb96e4ad0d0389267fe4f36968772e24", [:mix], [{:benchee, ">= 0.99.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}, {:benchee_json, "~> 1.0", [hex: :benchee_json, repo: "hexpm", optional: false]}], "hexpm", "b00a181af7152431901e08f3fc9f7197ed43ff50421a8347b0c80bf45d5b3fef"},
4+
"benchee_json": {:hex, :benchee_json, "1.0.0", "cc661f4454d5995c08fe10dd1f2f72f229c8f0fb1c96f6b327a8c8fc96a91fe5", [:mix], [{:benchee, ">= 0.99.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "da05d813f9123505f870344d68fb7c86a4f0f9074df7d7b7e2bb011a63ec231c"},
35
"db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"},
46
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
57
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},

0 commit comments

Comments
 (0)