Skip to content

Commit 1531a86

Browse files
committed
Add comparison of ets vs. gen server
1 parent e26d8c0 commit 1531a86

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,42 @@ sort/2 4.93 K - 1.05x slower
246246
sort_by/2 4.81 K - 1.08x slower
247247
```
248248

249+
#### Retrieving state from ets tables vs. Gen Servers [code](code/general/ets_vs_gen_server.exs)
250+
251+
There are many differences between Gen Servers and ets tables, but many people
252+
have often praised ets tables for being extremely fast. For the simple case of
253+
retrieving information from a key-value store, the ets table is indeed much
254+
faster for lookups. For more complicated use cases, and for comparisons of
255+
writes instead of reads, further benchmarks are needed, but so far ets lives up
256+
to its reputation for speed.
257+
258+
```
259+
Operating System: macOS
260+
CPU Information: Intel(R) Core(TM) i5-4260U CPU @ 1.40GHz
261+
Number of Available Cores: 4
262+
Available memory: 8.589934592 GB
263+
Elixir 1.7.0-dev
264+
Erlang 20.2
265+
Benchmark suite executing with the following configuration:
266+
warmup: 2.00 s
267+
time: 10.00 s
268+
parallel: 1
269+
inputs: none specified
270+
Estimated total run time: 24.00 s
271+
272+
273+
Benchmarking ets table...
274+
Benchmarking gen server...
275+
276+
Name ips average deviation median
277+
ets table 9.18 M 0.109 μs ±555.09% 0.100 μs
278+
gen server 0.34 M 2.97 μs ±1954.50% 3.00 μs
279+
280+
Comparison:
281+
ets table 9.18 M
282+
gen server 0.34 M - 27.24x slower
283+
```
284+
249285
## Something went wrong
250286

251287
Something look wrong to you? :cry: Have a better example? :heart_eyes: Excellent!

code/general/ets_vs_gen_server.exs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
defmodule RetrieveState.Fast do
2+
def get_state(ets_pid) do
3+
:ets.lookup(ets_pid, :stored_state)
4+
end
5+
end
6+
7+
defmodule StateHolder do
8+
use GenServer
9+
10+
def init(_), do: {:ok, %{stored_state: :returned_state}}
11+
12+
def start_link(state \\ []), do: GenServer.start_link(__MODULE__, state, name: __MODULE__)
13+
14+
def get_state(key), do: GenServer.call(__MODULE__, {:get_state, key})
15+
16+
def handle_call({:get_state, key}, _from, state), do: {:reply, state[key], state}
17+
end
18+
19+
defmodule RetrieveState.Slow do
20+
def get_state do
21+
StateHolder.get_state(:stored_state)
22+
end
23+
end
24+
25+
defmodule RetrieveState.Benchmark do
26+
def benchmark do
27+
ets_pid = :ets.new(:state_store, [:set, :public])
28+
:ets.insert(ets_pid, {:stored_state, :returned_state})
29+
StateHolder.start_link()
30+
31+
Benchee.run(
32+
%{
33+
"ets table" => fn -> RetrieveState.Fast.get_state(ets_pid) end,
34+
"gen server" => fn -> RetrieveState.Slow.get_state() end
35+
},
36+
time: 10,
37+
print: [fast_warning: false]
38+
)
39+
end
40+
end
41+
42+
RetrieveState.Benchmark.benchmark()

0 commit comments

Comments
 (0)