Thoughts on laziness (long)
matthias@REDACTED
matthias@REDACTED
Thu Oct 19 15:33:55 CEST 2000
> Robert Virding wrote:
> > I [...] have [not] yet come across any applications in Erlang
> > where it [laziness] would have been useful.
Jeremy Strazhiem wrote:
> However, I think Okasaki's amortized data structures might alone
> provide a good reason for some call-by-need laziness features.
Writing data structures in functional languages leads to embarassment:
almost no matter what you do, it's usually slower and often also
has worse big-O behaviour than the equivalent in a language which
allows destructive update.
One solution is to come up with elegant but complicated data
structures such as Okasaki's. Many of the more attractive ones require
lazy semantics. If you go down that road, you can brag on
comp.lang.functional that your functional language now also supports
monadical-recursive-slowdown-higher-order-transmogrification. You also
scare off many potential users.
Another solution is to just provide hashtables a la ETS. Nowhere near
as elegant, but (a) it doesn't require turning the language's
semantics upside down and (b) it's reasonable to assume it's faster*.
Matthias
------------------------------
* Every attempt I've seen to build a clever, general data structure in
Erlang has resulted in something that's slower than either lists or
ETS. Two examples:
ra_list
ra_list is one of Okasaki's data structures. It's a data
structure with both list-like and array-like behaviour;
you get O(log N) access to any element AND O(1) head()/tail()
gb_trees
gb_trees is on the user contributions page at erlang.org.
As far as I can tell, it's supposed to have O(log N)
access to elements. The documentation makes no claims
beyond "highly efficient".
Doing a quick benchmark doesn't give very encouraging results.
Sum: take a list of numbers 1..N and sum them (not Gauss' way ;-)
Update: change the 3rd, middle and 3rd-last elements in a list
-----list------ ------ra-list-- -------ets----- gb_tree
N sum update sum update sum update update
----------------------------------------------------------------------
100 107 197 962 84 1660 50 87
1000 921 3666 9903 127 16k 60 89
10k 9324 46k 93k 168 168k 74 96
100k 493k 660k 1357k 188 2109k 84 97
The table shows execution time, i.e. larger numbers are worse.
I can't see why anyone would want to use a gb_tree---ETS is
faster at the very operation gb_tree is supposed to be really
good at. The picture for ra_list is a little more complex, but
it doesn't make me want to jump up and down saying "yay! ra-lists".
Reasons why the above tests might be complete crap:
- I might have implemented ra-list really badly
- The above benchmark might be contrived specially to make
ETS look good. Then again, with such small tuples, I think
it's a worst-case for ETS.
- I might just be showing that the current Erlang implementation
sucks. Maybe ETOS or HIPE can show much better results for
purely functional data structures.
- I wasn't super-careful with the timing, e.g. it's all the
same Erlang machine, so garbage collection from earlier test
runs might have perturbed the results.
Source code is available on request if someone wants to investigate
this some more.
--- eot ---
More information about the erlang-questions
mailing list