Ecto SQL sigil

703 views
Skip to first unread message

benjamin...@gmail.com

unread,
Oct 27, 2024, 5:14:33 PM10/27/24
to elixir-ecto
Hey there,

I've been experimenting with creating an Ecto SQL sigil, and I'm wondering if it's possible to validate interpolation in a macro sigil.

```
id = 1
~SQL"select * from users where id = #{id}"
```

FYI, getting the information to validate column types is straightforward as the SQL standard has the information schema. For any non-compliant RDBMS, the adapter structure would make it straightforward to implement specific queries.

Ben Schultzer

unread,
Oct 27, 2024, 7:22:59 PM10/27/24
to elixi...@googlegroups.com
After looking into other sigil implementation e.g Phoenix ~p then I believe the best I would be able to do is generating if clause for the vars that are used in a interpolation, that would give us runtime validation, which I think it good enough for a POC. But I’m still interested if anyone know if we could archive compile-time validation for the sigil.

Technically we could create a lock file with all the information of the columns, but not sure if there would be any road blocks.
--
You received this message because you are subscribed to a topic in the Google Groups "elixir-ecto" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-ecto/8MOkRFAdLZc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-ecto+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-ecto/98c2f8fe-7d59-4e7d-8d77-b46793f23dban%40googlegroups.com.

benjamin...@gmail.com

unread,
Nov 26, 2024, 2:01:51 PM11/26/24
to elixir-ecto
I figured out most of the issues I had with creating a sigil and interpolation; the only thing left is guarding against SQL injection and casting to the proper type based on table information / Ecto Schema.

I've used nimle_persec for parsing, and my code is less than 200 LOC.

```
iex(192)> ~SQL[select id, (select id, COALESCE(id,null) from users) from users]
%{
  select: [
    "id",
    %{select: ["id", {:coalesce, [["id", :null]]}], from: ["users"]}
  ],
  from: ["users"]
}
```

```
iex(192)> sub = "File.read!(\"/mix.lock\")"
iex(193)> ~SQL[where id = "1" select #{1}, #{sub}, #{1 + 1} from users]
%{
  select: [1, "File.read!(\"/mix.lock\")", 2],
  where: ["id", :=, ~c"\"1\""],
  from: ["users"]
}
```

I think it would be nice to an SQL sigil in Ecto, and AFAIK they can still be composable in the same way Ecto.Query are.

Is there any interest from the core team to see this?

On Sunday, October 27, 2024 at 7:22:59 PM UTC-4 benjamin...@gmail.com wrote:
After looking into other sigil implementation e.g Phoenix ~p then I believe the best I would be able to do is generating if clause for the vars that are used in a interpolation, that would give us runtime validation, which I think it good enough for a POC. But I’m still interested if anyone know if we could archive compile-time validation for the sigil.

Technically we could create a lock file with all the information of the columns, but not sure if there would be any road blocks.

On Sunday, October 27, 2024, benjamin...@gmail.com <benjamin...@gmail.com> wrote:
Hey there,

I've been experimenting with creating an Ecto SQL sigil, and I'm wondering if it's possible to validate interpolation in a macro sigil.

```
id = 1
~SQL"select * from users where id = #{id}"
```

FYI, getting the information to validate column types is straightforward as the SQL standard has the information schema. For any non-compliant RDBMS, the adapter structure would make it straightforward to implement specific queries.

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-ecto" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-ecto/8MOkRFAdLZc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-ecto...@googlegroups.com.

José Valim

unread,
Nov 26, 2024, 2:41:24 PM11/26/24
to elixi...@googlegroups.com
I recommend to continue exploring it as a separate library for now. :) Thanks for reaching out!


You received this message because you are subscribed to the Google Groups "elixir-ecto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-ecto/b7b8953c-0567-4f68-89df-f9c06799cc54n%40googlegroups.com.

benjamin...@gmail.com

unread,
Feb 20, 2025, 10:32:54 AMFeb 20
to elixir-ecto
Getting ready to publish an MVP of an Ecto.SQL sigil library.

The biggest advantage I see with sigils is that we can separate querying database and data transformation in Elixir. Here I mostly think about how the select macro works.

However, each solution will also have pros and cons. One of the cons I'm running into is how to solve the mapping from database results and Ecto.Schema. Initially, I thought of leveraging Enummerable and Collectable protocols.

The enumerable implementation for Ecto.SQL would query the database and return the results which could be mapped by the Collectable implementation Enum.into(~SQL[select id, email, inserted_at, updated_at from users], %User{}).

I'm not sure if you ever thought about leveraging the two protocols when developing Ecto, if you did, is there something I'm missing for why this is not a good idea, since to me separation of concerns sounds like a big win for extensibility and maintainability. 

José Valim

unread,
Feb 20, 2025, 10:59:05 AMFeb 20
to elixi...@googlegroups.com
Thank you for the update. Just one suggestion, consider calling it EctoSQL or similar, as if one day we want to add it to Ecto, it would be at Ecto.SQL :)


benjamin...@gmail.com

unread,
Mar 1, 2025, 1:44:32 PMMar 1
to elixir-ecto
I have released an MVP: https://hexdocs.pm/sql https://github.com/elixir-dbvisor/sql

There is still quite a lot to do on the parser side, e.g. tokenize DDL etc. (we don't break user's queries, so tokens that are not recognized by the parser, would be passed through as :ident tokens)

It is not my best work by far, I've struggled a lot with the parser and API.

I would appreciate any feedback since this has just been me fiddling with it.

benjamin...@gmail.com

unread,
Apr 1, 2025, 7:07:48 PMApr 1
to elixir-ecto
Against all odds I have built a generated lexer and parser from the 2023 SQL BNF https://github.com/elixir-dbvisor/sql/pull/5 trying to stuff the grammar down leex and yeec turned out to be futile. There does exist some hand written Leex and Yeec SQL parser out there.

This also gave a decent 2x performance improvement, and I’m sure there is more gains to be made with optimization string generation.

I haven’t seen anyone leveraging Mix Task for parser generators, so I’m still interested in some feedback.

When it comes to enforcing any grammer rules, only encapsulation is enforced, but should be fairly simple to add additional checks in the lexer or parser.

benjamin...@gmail.com

unread,
Apr 13, 2025, 2:15:10 PMApr 13
to elixir-ecto
Great news, with https://github.com/elixir-dbvisor/sql/pull/6 we're now conformant with SQL 2016, with over 900 generated tests.

benjamin...@gmail.com

unread,
Apr 20, 2025, 5:41:01 PMApr 20
to elixir-ecto
I got exciting news, sql is between 400-650x faster then Ecto to generate SQL. I had not expected these results since sql does not currently build iodata.


➜  sql git:(main) ✗ mix sql.bench
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 64 GB
Elixir 1.18.0
Erlang 27.2
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 56 s

Benchmarking Ecto.Repo.to_sql ...
Benchmarking inspect ...
Benchmarking to_sql ...
Benchmarking to_stirng ...
Calculating statistics...
Formatting results...

Name                       ips        average  deviation         median         99th %
to_sql                  4.88 K        0.20 ms    ±21.12%       0.198 ms        0.31 ms
to_stirng               4.58 K        0.22 ms     ±2.98%        0.22 ms        0.24 ms
inspect                 0.24 K        4.18 ms     ±3.00%        4.16 ms        4.54 ms
Ecto.Repo.to_sql     0.00747 K      133.89 ms     ±4.22%      132.76 ms      148.82 ms

Comparison:
to_sql                  4.88 K
to_stirng               4.58 K - 1.06x slower +0.0133 ms
inspect                 0.24 K - 20.41x slower +3.98 ms
Ecto.Repo.to_sql     0.00747 K - 653.15x slower +133.68 ms

Memory usage statistics:

Name                Memory usage
to_sql                   0.38 MB
to_stirng               0.153 MB - 0.40x memory usage -0.22888 MB
inspect                  4.88 MB - 12.80x memory usage +4.50 MB
Ecto.Repo.to_sql       179.35 MB - 470.13x memory usage +178.97 MB

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



➜  sql git:(main) ✗ mix sql.bench
Compiling 1 file (.ex)
Generated sql app
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 64 GB
Elixir 1.18.0
Erlang 27.2
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 56 s

Benchmarking Ecto.Repo.to_sql ...
Benchmarking inspect ...
Benchmarking to_sql ...
Benchmarking to_stirng ...
Calculating statistics...
Formatting results...

Name                       ips        average  deviation         median         99th %
to_sql                 4900.64        0.20 ms    ±17.90%       0.198 ms        0.31 ms
to_stirng                21.90       45.65 ms     ±1.91%       45.45 ms       48.89 ms
inspect                  19.60       51.01 ms     ±2.26%       50.64 ms       54.87 ms
Ecto.Repo.to_sql          7.55      132.39 ms     ±2.40%      131.83 ms      142.37 ms

Comparison:
to_sql                 4900.64
to_stirng                21.90 - 223.73x slower +45.45 ms
inspect                  19.60 - 249.97x slower +50.80 ms
Ecto.Repo.to_sql          7.55 - 648.81x slower +132.19 ms

Memory usage statistics:

Name                     average  deviation         median         99th %
to_sql                   0.38 MB     ±0.00%        0.38 MB        0.38 MB
to_stirng               22.05 MB     ±0.00%       22.05 MB       22.05 MB
inspect                 26.78 MB     ±0.00%       26.78 MB       26.78 MB
Ecto.Repo.to_sql       179.35 MB     ±0.00%      179.35 MB      179.35 MB

Comparison:
to_sql                   0.38 MB
to_stirng               22.05 MB - 57.79x memory usage +21.67 MB
inspect                 26.78 MB - 70.19x memory usage +26.40 MB
Ecto.Repo.to_sql       179.35 MB - 470.13x memory usage +178.97 MB

benwil...@gmail.com

unread,
Apr 22, 2025, 3:41:23 PMApr 22
to elixir-ecto
Can you show the full benchmark file you're using? The one I see on the git repo doesn't have any ecto examples. A 130ms average generation time or even a 50ms inspect time says something maybe be wrong with the benchmarking setup, as those are crazy long times.

José Valim

unread,
Apr 22, 2025, 4:19:28 PMApr 22
to elixi...@googlegroups.com
Also make sure protocols are consolidated just in case :)



benjamin...@gmail.com

unread,
Apr 28, 2025, 5:28:06 PMApr 28
to elixir-ecto
Couldn't find any issues with protocols, but here are the changes: https://github.com/elixir-dbvisor/sql/pull/7/files which gives us 4-600x improvements over Ecto at generating SQL at runtime or compile time.

Ben, the numbers represent 10000 queries. So we're blowing Ecto out of the water right now.

benjamin...@gmail.com

unread,
Apr 28, 2025, 5:29:58 PMApr 28
to elixir-ecto
As I'm learning as I go, then I properly left a ton of optimization on the table.

José Valim

unread,
Apr 28, 2025, 5:55:32 PMApr 28
to elixi...@googlegroups.com

benjamin...@gmail.com

unread,
May 3, 2025, 4:53:49 PMMay 3
to elixir-ecto
I was thinking about doing everything at compile time, which is possible, but it might not be needed with these numbers:

```
➜  sql git:(optimize-sql-generation) ✗ mix sql.bench

Compiling 1 file (.ex)
Generated sql app
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 64 GB
Elixir 1.18.0
Erlang 27.2
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 56 s

Benchmarking ecto ...

Benchmarking inspect ...
Benchmarking to_sql ...
Benchmarking to_stirng ...
Calculating statistics...
Formatting results...

Name                ips        average  deviation         median         99th %
to_stirng        417.33        2.40 ms     ±2.47%        2.37 ms        2.56 ms
to_sql           414.15        2.41 ms     ±3.43%        2.39 ms        2.64 ms
inspect          165.55        6.04 ms     ±3.85%        5.94 ms        6.64 ms
ecto               6.97      143.45 ms     ±2.01%      142.71 ms      160.84 ms

Comparison:
to_stirng        417.33
to_sql           414.15 - 1.01x slower +0.0184 ms
inspect          165.55 - 2.52x slower +3.64 ms
ecto               6.97 - 59.87x slower +141.06 ms


Memory usage statistics:

Name         Memory usage
to_stirng         4.27 MB
to_sql            4.50 MB - 1.05x memory usage +0.23 MB
inspect           9.00 MB - 2.11x memory usage +4.73 MB
ecto            202.87 MB - 47.52x memory usage +198.60 MB


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

benjamin...@gmail.com

unread,
May 4, 2025, 9:33:10 PMMay 4
to elixir-ecto

I’m very excited for the new release of sql, which comes with best in class performance and memory usage, with a minimum of 50x compared to Ecto.

The test suite has also gotten an overhaul with over 900 test, testing the conformance of SQL 2016.

sql does now also supports prepared queries.

Checkout the https://github.com/elixir-dbvisor/sql/blob/main/CHANGELOG.md for more!

benjamin...@gmail.com

unread,
May 7, 2025, 10:46:22 AMMay 7
to elixir-ecto

Hey Jose, I’m getting to the point where I want to build a POC that marries Ecto and SQL, so a schema can be mapped into SQL and the result set can be transformed into Ecto Schemas. Do you got any pointers, or things you would like to see?

José Valim

unread,
May 7, 2025, 10:48:41 AMMay 7
to elixi...@googlegroups.com
Not at the moment, sorry. I have too many things on my plate at the moment. I would try to start a discussion with the other maintainers in the issues tracker (or on Discord).


benjamin...@gmail.com

unread,
May 8, 2025, 4:36:29 PMMay 8
to elixir-ecto
Awesome,

Here is a minimal example:

```
iex(1)> Enum.into(~SQL[from users select *], User.new())

16:31:00.046 [debug] QUERY OK db=0.4ms decode=0.7ms queue=1.6ms
select * from users []
[
  #User<
    __meta__: #Ecto.Schema.Metadata<:built, "users">,
    id: 1,
    name: "john",
    age: 18,
    ...
  >
]
```

```
defmodule User do
  use Ecto.Schema

  schema "users" do
    field :name, :string
    field :age, :integer, default: 0
    field :password, :string, redact: true
  end

  def new, do: %User{}

  defimpl Collectable do
    def into(%struct{__meta__: %Ecto.Schema.Metadata{}} = schema) do
      {[], fn rows, _acc -> Enum.map(rows, &(Ecto.Changeset.apply_action!(Ecto.Changeset.cast(schema, &1, struct.__schema__(:fields)), :insert))) end}
    end
  end
end
```

```
defmodule SQL.Repo do
  use Ecto.Repo, otp_app: :sql, adapter: Ecto.Adapters.Postgres

  defimpl Enumerable, for: SQL do
    def count(_enumerable) do
      {:error, __MODULE__}
    end
    def member?(_enumerable, _element) do
      {:error, __MODULE__}
    end
    def reduce(%SQL{} = enumerable, _acc, _fun) do
      {sql, params} = SQL.to_sql(enumerable)
      result = SQL.Repo.query!(sql, params)
      {:done, Enum.map(result.rows, &Map.new(Enum.zip(result.columns, &1)))}
    end
    def slice(_enumerable) do
      {:error, __MODULE__}
    end
  end
end
```

Obvious above is a minimal and unoptimized example that is leveraging Ecto.Changeset for the heavy lifting for this.

benjamin...@gmail.com

unread,
May 10, 2025, 1:07:57 PMMay 10
to elixir-ecto
As I want to make sure, that we have room to do more at compile time, I decided to try improve runtime behavoir just a bit. And we're still getting prepared queries. Putting to rest the myth that we can't have prepared queries at compile time and exellent runtime behavoir. This also completely obliterates by conformance tests form 11.5 seconds to under 2 seconds.

➜  sql git:(main) mix sql.bench

Compiling 1 file (.ex)

Generated sql app

Operating System: macOS

CPU Information: Apple M1 Max

Number of Available Cores: 10

Available memory: 64 GB

Elixir 1.18.3

Erlang 27.3.3

JIT enabled: true


Benchmark suite executing with the following configuration:

warmup: 2 s

time: 10 s

memory time: 2 s

reduction time: 0 ns

parallel: 1

inputs: none specified

Estimated total run time: 56 s


Benchmarking ecto ...

Benchmarking inspect ...

Benchmarking to_sql ...

Benchmarking to_string ...

Calculating statistics...

Formatting results...


Name                ips        average  deviation         median         99th %

to_string        2.10 K        0.48 ms     ±5.77%        0.47 ms        0.59 ms

to_sql           1.94 K        0.52 ms    ±15.55%        0.50 ms        0.78 ms

inspect          0.21 K        4.76 ms    ±11.22%        4.64 ms        6.37 ms

ecto          0.00678 K      147.55 ms     ±1.98%      147.55 ms      157.09 ms


Comparison: 

to_string        2.10 K

to_sql           1.94 K - 1.09x slower +0.0406 ms

inspect          0.21 K - 10.01x slower +4.28 ms

ecto          0.00678 K - 310.47x slower +147.07 ms


Memory usage statistics:


Name         Memory usage

to_string         1.30 MB

to_sql            1.53 MB - 1.18x memory usage +0.23 MB

inspect           7.63 MB - 5.89x memory usage +6.33 MB

ecto            202.87 MB - 156.62x memory usage +201.57 MB


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


➜  sql git:(main) mix deps.get && mix sql.gen.test ../sqltest/standards/2016 && mix test

Resolving Hex dependencies...

Resolution completed in 0.024s

Unchanged:

  benchee 1.3.1

  db_connection 2.7.0

  decimal 2.3.0

  deep_merge 1.0.0

  earmark_parser 1.4.43

  ecto 3.12.5

  ecto_sql 3.12.1

  ex_doc 0.37.2

  makeup 1.2.1

  makeup_elixir 1.0.1

  makeup_erlang 1.0.2

  nimble_parsec 1.4.2

  postgrex 0.20.0

  statistex 1.0.0

  telemetry 1.3.0

  yamerl 0.10.0

All dependencies are up to date

Compiling 4 files (.ex)

Generated sql app

* creating test/conformance/e_test.exs

* creating test/conformance/f_test.exs

* creating test/conformance/s_test.exs

* creating test/conformance/t_test.exs

Compiling 4 files (.ex)

Generated sql app

Running ExUnit with seed: 856209, max_cases: 20


............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Finished in 1.9 seconds (1.9s async, 0.00s sync)

956 tests, 0 failures



➜  sql git:(main) mix deps.get && mix sql.gen.test ../sqltest/standards/2016 && mix test

Resolving Hex dependencies...

Resolution completed in 0.025s

Unchanged:

  benchee 1.3.1

  db_connection 2.7.0

  decimal 2.3.0

  deep_merge 1.0.0

  earmark_parser 1.4.43

  ecto 3.12.5

  ecto_sql 3.12.1

  ex_doc 0.37.2

  makeup 1.2.1

  makeup_elixir 1.0.1

  makeup_erlang 1.0.2

  nimble_parsec 1.4.2

  postgrex 0.20.0

  statistex 1.0.0

  telemetry 1.3.0

  yamerl 0.10.0

All dependencies are up to date

* creating test/conformance/e_test.exs

* creating test/conformance/f_test.exs

* creating test/conformance/s_test.exs

* creating test/conformance/t_test.exs

Running ExUnit with seed: 149448, max_cases: 20


.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Finished in 11.5 seconds (11.5s async, 0.00s sync)

961 tests, 0 failures

benjamin...@gmail.com

unread,
Jul 22, 2025, 10:24:26 PMJul 22
to elixir-ecto

➜  sql git:(main) mix sql.bench

Operating System: macOS

CPU Information: Apple M1 Max

Number of Available Cores: 10

Available memory: 64 GB

Elixir 1.18.3

Erlang 27.3.3

JIT enabled: true


Benchmark suite executing with the following configuration:

warmup: 2 s

time: 5 s

memory time: 2 s

reduction time: 2 s

parallel: 1

inputs: 1..100_000

Estimated total run time: 1 min 50 s


Benchmarking comptime ecto with input 1..100_000 ...

Benchmarking comptime inspect with input 1..100_000 ...

Benchmarking comptime to_sql with input 1..100_000 ...

Benchmarking comptime to_string with input 1..100_000 ...

Benchmarking lex with input 1..100_000 ...

Benchmarking parse with input 1..100_000 ...

Benchmarking runtime ecto with input 1..100_000 ...

Benchmarking runtime inspect with input 1..100_000 ...

Benchmarking runtime to_sql with input 1..100_000 ...

Benchmarking runtime to_string with input 1..100_000 ...

Calculating statistics...

Formatting results...


##### With input 1..100_000 #####

Name                         ips        average  deviation         median         99th %

comptime to_sql          22.05 M       45.36 ns ±31872.80%          42 ns          42 ns

comptime to_string       21.82 M       45.84 ns ±40289.89%          42 ns          42 ns

runtime to_string        21.72 M       46.04 ns ±41584.01%          42 ns          42 ns

runtime to_sql           20.17 M       49.59 ns ±54043.19%          42 ns          42 ns

comptime inspect          4.06 M      246.19 ns ±11260.76%         167 ns         333 ns

runtime inspect           3.87 M      258.43 ns ±10897.27%         167 ns         333 ns

parse                     1.74 M      573.30 ns  ±2688.99%         541 ns         667 ns

lex                       0.23 M     4294.48 ns   ±198.77%        4167 ns        4958 ns

runtime ecto             0.195 M     5139.65 ns   ±199.40%        4958 ns        7250 ns

comptime ecto            0.193 M     5186.87 ns   ±108.00%        4667 ns       16959 ns


Comparison: 

comptime to_sql          22.05 M

comptime to_string       21.82 M - 1.01x slower +0.48 ns

runtime to_string        21.72 M - 1.01x slower +0.68 ns

runtime to_sql           20.17 M - 1.09x slower +4.23 ns

comptime inspect          4.06 M - 5.43x slower +200.84 ns

runtime inspect           3.87 M - 5.70x slower +213.07 ns

parse                     1.74 M - 12.64x slower +527.95 ns

lex                       0.23 M - 94.68x slower +4249.13 ns

runtime ecto             0.195 M - 113.32x slower +5094.30 ns

comptime ecto            0.193 M - 114.36x slower +5141.51 ns


Memory usage statistics:


Name                  Memory usage

comptime to_sql               24 B

comptime to_string             0 B - 0.00x memory usage -24 B

runtime to_string              0 B - 0.00x memory usage -24 B

runtime to_sql                24 B - 1.00x memory usage +0 B

comptime inspect             344 B - 14.33x memory usage +320 B

runtime inspect              344 B - 14.33x memory usage +320 B

parse                       2432 B - 101.33x memory usage +2408 B

lex                        11976 B - 499.00x memory usage +11952 B

runtime ecto               21336 B - 889.00x memory usage +21312 B

comptime ecto              18848 B - 785.33x memory usage +18824 B


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


Reduction count statistics:


Name               Reduction count

comptime to_sql                  2

comptime to_string               7 - 3.50x reduction count +5

runtime to_string                7 - 3.50x reduction count +5

runtime to_sql                   2 - 1.00x reduction count +0

comptime inspect                28 - 14.00x reduction count +26

runtime inspect                 28 - 14.00x reduction count +26

parse                          210 - 105.00x reduction count +208

lex                            154 - 77.00x reduction count +152

runtime ecto                  1193 - 596.50x reduction count +1191

comptime ecto                 1132 - 566.00x reduction count +1130


**All measurements for reduction count were the same**


Great news, lexing and parsing at runtime is now faster then Ecto. 

benjamin...@gmail.com

unread,
Aug 23, 2025, 2:30:06 PMAug 23
to elixir-ecto
With the upcoming changes   

We’re getting ready to take the next step in benchmarking, we’ll benchmark two new phoenix applications and load tests them to showcase the difference. I don’t know what to expect, but I’m sure there will be surprises, as there has been consistently in this journey, at no point did  I think that this library would be faster then Ecto, but will this matter in the real would? Stay tuned!
Reply all
Reply to author
Forward
0 new messages