jchrist

jchrist

Hi folks,

In a library I’m working on we allow the user to implement “cache adapters” that implement our cache behaviour and the library can work with it.

I’ve recently introduced Erlang’s QLC module and I find it very intuitive to work with: we can now essentially ask users to implement a QLC table and all other read functions can then be defined by our library, with no extra work for the user. It also supports joins, which comes in very handy :slight_smile:

The reason I’m posting is that I was benchmarking this in comparison to our previous implementation and realized that when the QLC query is written in Elixir using :qlc.string_to_handle/3 performance seems to be worse than when it is written natively in Erlang using the parse transform. A small excerpt (the native means the QLCs are written directly in Erlang):

Name                                     ips        average  deviation         median         99th %
native, naive                      388190.23     0.00258 ms   ±679.57%     0.00188 ms     0.00939 ms
naive                               25145.54      0.0398 ms    ±20.92%      0.0373 ms      0.0626 ms
native, nested                         23.21       43.09 ms    ±10.36%       41.71 ms       65.80 ms
native, naive, traversed               23.06       43.36 ms     ±9.46%       42.61 ms       59.01 ms
naive, traversed                        1.55      644.14 ms     ±2.32%      639.93 ms      665.63 ms
nested                                  0.36     2776.43 ms     ±0.00%     2776.43 ms     2776.43 ms

In terms of memory usage, the queries written in Erlang also seem to perform better (table size is 100_000 elements):

Name                              Memory usage
native, naive                       0.00218 MB
naive                                0.0116 MB - 5.31x memory usage +0.00941 MB
native, nested                        12.75 MB - 5844.20x memory usage +12.75 MB
native, naive, traversed              12.75 MB - 5845.10x memory usage +12.75 MB
naive, traversed                     346.34 MB - 158723.67x memory usage +346.33 MB
nested                              1064.87 MB - 488021.91x memory usage +1064.86 MB

The nested query is a bit special because it sticks two query handles together. I imagine that perhaps in the Erlang module there is some optimization going on that I can’t do from Elixir with string_to_handle.

However, for the naive query, the speed difference is not very clear to me. Did I maybe make a mistake in benchmarking? The query setup in Elixir:

qh = :ets.table(tab)
qh0 = :qlc.string_to_handle('[{Id, Id, Value} || {Id, Value} <- Handle, Id =:= RequestedId].', [], Handle: qh, RequestedId: 500_000)

And in Erlang (qh is passed in by the benchmarking script):

qh0(Tab, RequestedId) ->
    qlc:q([{Id, Id, Value} || {Id, Value} <- Tab, Id =:= RequestedId]).

If I print the query information using :qlc.info I see the same for both Erlang and Elixir. What could explain this difference?

The full benchmarking script I used can be found here: Benchmarking of Erlang's QLC module in various ways · GitHub

Showing Posts 2 to 1

jchrist

jchrist OP

Ahh, why didn’t I think of that..

That was indeed the reason! I wonder how this makes so much of a difference :thinking:

Thank you for the help!

josevalim

josevalim

Creator of Elixir

What happens if you also write the Erlang versions using string_to_handle? Perhaps the issue is not Elixir vs Erlang, but rather the qlc API being used?

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews