oegma2

oegma2

Why is my random number lookup slow using lists?

Hi, I am new to Elixir world and still have a long way to go, but starting with a basic problem I’ve been using to learn any new language - one with monkies hitting random keys and see if they can write a chapter out of Shakespeare’s book :slight_smile: - but in order to solve this problem, I need to generate a random letter, representing the monkey’s hitting a key…So after a bit of googling found an option using List and rand.uniform(…) to return a random “key” out of a fixed list

The problem is, doing this function over and over is a key component and is really slow compared to any other language… I know Elixir and the BEAM VM are designed for reliability and thus immutable obj can slow things down…

Is there any solution to speed this code up below, so that I can continue the journey with Elixir and write a program that can spawn million’s of monkies, all hitting keys

chars = ‘ABCDEFGHIJKLMNOPQRSTUVW’
data = List.to_tuple(chars)

for x <- 0…1000000 do
elem(data, :rand.uniform(22))
end

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

He wasn’t providing a faster solution, he was showing how the code underlying your existing solution worked, demonstrating that it was O(N).

Probably the fastest thing is to just compute a random number between 0 and 22 and add the correct ASCII offset.

random_char = [:random.uniform(22) + 65]
hauleth

hauleth

Except I would write it as:

random_char = [:rand.uniform(?Z - ?A) + ?A)]

For less “magic numbers”. Also :rand is preferred solution over :random.

However I am not sure if Enum.random(?A..?Z) isn’t optimised for such case (and if not it probably would be nice addition).

EDIT:

Enum.random(?A..?Z) will run in constant time and space, so it would be the best and the fastest solution.

cc @oegma2

hauleth

hauleth

Lists do not support random access and access is linear, so to get nth element you need n steps. In other words the Enum.at/2 for list will be implemented as:

def at([], _), do: nil
def at([val | rest], 0), do: val
def at([_ | rest], n) when n > 0, do: at(rest, n - 1)
rvirding

rvirding

Creator of Erlang

Yes, this is explicitly mentioned in the module rand docs:

The builtin random number generator algorithms are not cryptographically strong. If a cryptographically strong random number generator is needed, use something like crypto:rand_seed/0.

hauleth

hauleth

For cryptographically secure rands you need to use :crypto.random_bytes/1, :rand isn’t crypto safe either.

Where Next?

Popular in Questions Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
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
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
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
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement