Agent is a simple solution that could work for smaller loads and a few client processes. ETS table should usually perform better, and can support concurrent clients, i.e. you could have simultaneous multiple readers/writers - something not possible with Agent/GenServer. It is however very limited in terms of atomic operations, so it’s mostly suitable for simple k-v stuff, and some concurrent counters.
Personally, if I know that there will be multiple clients of a key-value store, I just go for …
That post probably offers better insight than I can.
There’s also this blog post which offers the following explanation:
An ETS based approach
Other times, if the Agent doesn’t cut it for you, you might something faster. In these cases ETS might be a good option. The good thing about ETS is that it will always be faster because it doesn’t go through the Erlang Scheduler, furthermore it also supports concurrent reads and writes, which the Agent does not. However, it’s a bit more limited when you want to do atomic operations. Overall it’s very well suited for a simple shared key/value store, but if it’s better suited or not for your specific problem, that’s up to you.
Finally, the approach that immediately came to my mind was not using a cache at all but using Task.asyn_stream
as described in this blog post
_This is the second part of Percy Grunwald's series on Elixir. Don't miss out on the first article on [Unicode matching in Elixir](https://exercism.io/blog/unicode-matching-in-elixir)._
Exercises on Exercism are small, synthetic, and often seemingly trivial. It’s easy to imagine that experienced practitioners would have nothing to learn from them. However, solving these synthetic problems can push you to learn and apply parts of your language that you may not have explored. This new learning can lead you to solve real-world problems more efficiently or more expressively.
[Parallel Letter Frequency](https://exercism.io/tracks/elixir/exercises/parallel-letter-frequency) is a medium difficulty exercise on [Exercism's Elixir Track](https://exercism.io/tracks/elixir) that unpacks a surprising number of interesting lessons. To solve this problem successfully your solution should execute in parallel in multiple worker processes. Achieving true parallelism in Elixir is surprisingly easy compared to other languages, but if you've never written concurrent code in Elixir, it may seem a little daunting. One of the things you'll discover in solving this exercise is how easy Elixir makes it to write code that can execute concurrently or in parallel. Applying these skills to your code can have a significant impact on the performance of your applications.
This exercise requires you to implement a function, `Frequency.frequency/2`, that determines the letter frequency in a list of strings. The calculation should be carried out in several worker processes, set by the `workers` argument:
```elixir
iex> Frequency.frequency(["Freude", "schöner", "Götterfunken"], workers)
%{
"c" => 1,
"d" => 1,
"e" => 5,
...
"ö" => 2
}
```
In this post, we'll explore concurrency in Elixir by making a working sequential solution to this exercise concurrent. However, before we jump into the code, let's take a moment to examine what "concurrency" and "parallelism" actually mean, and how to achieve both in Elixir vs. other languages.
This file has been truncated. show original
2 Likes