Skip to content

Instantly share code, notes, and snippets.

@seth
Created March 6, 2013 06:25
Show Gist options
  • Save seth/5097169 to your computer and use it in GitHub Desktop.
Save seth/5097169 to your computer and use it in GitHub Desktop.
Notes on comparing effectiveness of random list element selection as found in Erlang's pg2 vs using random:uniform. Also comparing effect under concurrent access of erlang:now() vs os:timestamp().
library("lattice")
z <- read.table("all.txt", colClasses=rep("integer", 4))
names(z) <- c("pg_rand", "pg_rand_os", "u_rand", "u_rand_os")
all <- stack(z)
names(all) <- c("item", "func")
tapply(all$item, all$func, table)
histogram(~item|func, data=all, type="count", breaks=0:50)
-module(rand_test).
-compile([export_all]).
pg_rand(L) ->
{_,_,X} = erlang:now(),
Idx = (X rem length(L)) + 1,
lists:nth(Idx, L).
pg_rand_os(L) ->
{_,_,X} = os:timestamp(),
Idx = (X rem length(L)) + 1,
lists:nth(Idx, L).
u_rand(L) ->
random:seed(erlang:now()),
Idx = random:uniform(length(L)),
lists:nth(Idx, L).
u_rand_os(L) ->
random:seed(os:timestamp()),
Idx = random:uniform(length(L)),
lists:nth(Idx, L).
test() ->
N = 10000,
Workers = 10,
ListSize = 50,
List = [ integer_to_list(I) || I <- lists:seq(1, ListSize) ],
work(N, Workers, List, fun pg_rand/1, "pg_rand.txt"),
work(N, Workers, List, fun u_rand/1, "u_rand.txt"),
work(N, Workers, List, fun u_rand_os/1, "u_rand_os.txt"),
work(N, Workers, List, fun pg_rand_os/1, "pg_rand_os.txt").
write_sample(Sample, Name) ->
{ok, Fd} = file:open(Name, [write]),
[ io:fwrite(Fd, "~B~n", [S]) || S <- Sample ],
file:close(Fd).
sample(N, L, F) ->
sample(N, L, F, []).
sample(0, _L, _F, Acc) ->
lists:reverse(Acc);
sample(N, L, F, Acc) ->
sample(N - 1, L, F, [<<"\n">>, F(L)| Acc]).
work(Workers, N, L, F, Name) ->
Parent = self(),
Pids = [ spawn(fun() -> worker(N, L, F, Parent) end)
|| _I <- lists:seq(1, Workers) ],
{ok, Fd} = file:open(Name, [write]),
gather_workers(Pids, Fd).
worker(N, L, F, Parent) ->
Ans = sample(N, L, F),
Parent ! {self(), Ans}.
gather_workers([Pid | Rest], Fd) ->
receive
{Pid, Ans} ->
file:write(Fd, Ans),
gather_workers(Rest, Fd)
end;
gather_workers([], Fd) ->
file:close(Fd).
erl -s rand_test test -s init stop
paste pg_rand.txt pg_rand_os.txt u_rand.txt u_rand_os.txt > all.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment