minhajuddin

minhajuddin

Defmap - embed maps into a module for faster/easier lookups. Feedback please

Defmap is a utility which allows you to embed a map into a module for faster/easier lookups.

https://hexdocs.pm/defmap/Defmap.html

Most Liked

sasajuric

sasajuric

Author of Elixir In Action

I’m not sure you need a lib and a macro for this. You can get the same thing with something like this (untested):

defmodule Foo do
  for {code, message} <- {400 => "Bad Request", 401 => "Unauthorized", 403 => "Forbidden"} do
    def get(unquote(code)), do: {:ok, unquote(message)}
  end
  def get(_), do: :error
end

I occasionally use this technique.

bbense

bbense

Well, there can be some performance advantages in functional heads vs just looking things up in a map. This is more or less the way unicode support is implemented in Elixir core.

I think I’d like this more if it did not use the Map get as the function name and I’d really like it a lot more if it wasn’t called Defmap. The function is really just get_constant, or even just constant or attribute. It’s a generic tool for exposing module attributes as functions. Map is just a convenient way to structure the input, you aren’t defining a Map in any practical sense at all.

The only thing wrong with this is actually the hardest part of programming, naming stuff. I think what it does is useful.

OvermindDL1

OvermindDL1

Ah that’s cool. :slight_smile:

minhajuddin

minhajuddin

Thanks for all the feedback guys :slight_smile:

I have benchmarked the simple map implementation from @Eiji

Elixir 1.3.3
Benchmark suite executing with the following configuration:
warmup: 2.0s
time: 5.0s
parallel: 1
Estimated total run time: 14.0s

Benchmarking defmap...
Benchmarking plainmap...

Name               ips        average  deviation         median
defmap          4.87 K      205.17 μs     ±6.77%      201.00 μs
plainmap        4.46 K      224.04 μs    ±11.79%      215.00 μs

Comparison: 
defmap          4.87 K
plainmap        4.46 K - 1.09x slower

The difference is performance is not huge. However, there is a huge difference in memory usage. I checked the memory usage of the defmap version using :observer.start (Please recommend a good memory profiling tool, I didn’t know any :slight_smile: ) and defmap used ~43mb of memory whereas plainmap used ~200mb, This was my initial assumption as for every lookup with the map implementation we are instantiating a full map and then selecting one value from it. You can checkout the test implementation @ https://github.com/minhajuddin/defmap_test

Eiji

Eiji

Ok, now I see your point.
Thanks for performance testing, they give me a lot to think about.

I have a feature request:
more configuration - allow to send opts like:

defmodule MyProject do
  YourLibrary.your_macro(my_first_map)
  YourLibrary.your_macro(my_second_map, [caller: :get_value])
  YourLibrary.your_macro(my_third_map, [private: true])
end

to allow define multiple embed maps (also private maps) into one module with different callers.
Your default configuration config.exs:

config :defmap, :default_opts,
  caller: :get,
  private: false

Where Next?

Popular in Libraries Top

New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
markmark206
simple_feature_flags is a tiny package that lets you turn features on or off based on which environment (e.g. localhost, staging, product...
New
sasajuric
I’d like to announce a small library called boundaries. This is an experimental project which explores the idea of enforcing boundaries ...
New
entone
ExARI An Elixir library for interfacing with Asterisk using the ARI protocol. Be sure to check out the example application https://git...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
woylie
I released Doggo, a collection of unstyled Phoenix components. Features Unstyled Phoenix components. Storybook that can be added to...
New
aditya7iyengar
Rummage.Ecto and Rummage.Phoenix provide ways to perform Searching, Sorting and Pagination over Ecto queries and Phoenix collections. Fo...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
Qqwy
Hello everyone, I wrote a small library today called MapDiff. It returns a map listing the (smallest amount of) changes to get from map...
New

Other popular topics Top

josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

Sub Categories:

We're in Beta

About us Mission Statement