[erlang-questions] Speedy unsort:shuffle/1,2 ?

Allan Wegan allanwegan@REDACTED
Sat May 29 07:19:47 CEST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> However, there are some constraints on this function. It needs to be
> generic enough, it needs to be fast enough and consume as little memory
> as possible. Three constraints that seldom spell success when combined.
> 
> My suggestion is included in this mail, but my question is: does anyone
> have a faster, more generic and less memory consuming shuffle function?

In an ideal world the following function would be realy fast (because of
O(length(List) of the compiler optimized list_rearrange/4:


% Call example: list_rearrange(fun randomizer/1, List)

- -export([
  list_rearrange/2,
  randomizer/1
]).

list_rearrange(_F, []  = L) -> L;
list_rearrange(_F, [_] = L) -> L;
list_rearrange(F, List) ->
  Input  = list_to_tuple(List),
  Length = tuple_size(Input),
  Output = erlang:make_tuple(Length, 'undefined'),
  list_rearrange(F, Input, Length, Output)
.

list_rearrange(_F, _Input, 0 = _Length, Output) -> tuple_to_list(Output);
list_rearrange( F,  Input,      Length, Output) ->
  {F_2, Chosen_pos} = F(Length),
  Chosen_element    = element(Chosen_pos, Input),
  Last_element      = element(Length,     Input),
  Input_2           = setelement(Chosen_pos, Input,  Last_element),
  Output_2          = setelement(Length,     Output, Chosen_element),
  list_rearrange(F_2, Input, Length - 1, Output_2)
.

randomizer(1) -> {fun randomizer/1, 1};
randomizer(N) -> {fun randomizer/1, crypto:rand_uniform(1, N)}.


But in the real world, the compiler does not realize, that we never
_can_ touch the original tuples given to list_rearrange/4 after the
setelement calls. list_rearrange/4 is not exported, tail recursive, and
in the same module only used as the _last_ statement in the function
that creates the tuples in its body.
The compiler produces code to copy the tuples in each call making
list_rearrange/4 O(length(List)^2)...


- -- 
Allan Wegan
Jabber: allanwegan@REDACTED
ICQ:    209459114
Phone:  +49 40 6732962 (Hansenet)
Schöneberger Strasse 60, 22149 Hamburg
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (MingW32)

iQEcBAEBAgAGBQJMAKPzAAoJENm5axHh7AcxrCwH/RKjyRJ1JacHZ4e5kZ1pPAMK
/oFsaYTfjpBbQLsJhRCQuaHkSPDkA1k2YHqbNRiuXuPCPW5eazcE5kmUM2c2IJW8
EeSThk3jWEVmnGmTZVOEdjOGqmp74izuhWiRlBxs9TceT9Ejnzth5Dhe9zcsqGdi
CDvj5A0oZHOv6EjKR/8FShGI1AxYQcIXgBvzKdomHeaXPPDzj3AKoDixSIWQgQoH
1joia4xXEmMz0ygsOhoMgXw2/plrAZWlr/WRLA7P97nG9Gp8WQ7dyPFcrWNu9KVY
yx7ak/hrPJLAlx6j+foo7QoFC8CFL8ljUelmca0gw2/msmGb7aOwrT9OlcWlXzo=
=qbql
-----END PGP SIGNATURE-----


More information about the erlang-questions mailing list