[erlang-questions] VM & BEAM Specs : idea for improving, the lists support
Denys Rtveliashvili
rtvd@REDACTED
Mon Aug 6 19:41:57 CEST 2007
> Of the many systems I've used in the past, the ones with "smart" lists
> were invariably worse than the ones with "dumb" ones. My favourite
> example is Interlisp-D, with CDR-coding and a smart CONS. Xerox Quintus
> Prolog, with "dumb" lists, ran list processing code 5 times faster on
> the same hardware. One would expect *idiomatic* Erlang code to be
> similarly slowed down by a "smart" implementation of lists.
>
Well.. Your mileage may vary. The difference of performance depends on
lots of things. So, you can tell the difference only if there are two
finely tuned implementations.
>> "Use unrolled linked lists to improve the performance"
> I have unrolled strict list code for Haskell and Clean.
> See http://www.cs.otago.ac.nz/staffpriv/ok/software.htm/
>
> A neural net program written in Haskell used 3650 seconds with
> plain lists and 3057 seconds (about 1.2 times faster). The best
> I've ever seen, on a benchmark doing practically nothing else,
> was 2 times faster. (By making it GHC-specific I could probably
> do somewhat better, but probably not much.) That was for
> numeric code where GHC's ability to treat !Double as unboxed
> paid off. Erlang has no such ability, so I suspect that we are
> looking at the 1.2 factor at best.
>
OK, you've got a performance penalty here. However, I assume you would
not argue that an unrolled list consumes less space. Also it has sense
to compare native implementations of dumb linked list and an unrolled
linked list. Otherwise you can have additional penalties you would not
get with a native version.
>> --- Idea #2:
>>
>> "Use resize-able vectors to store lists"
>>
>> I guess this change would give even more benefits comparing to the
>> Idea #1
>>
>
> My guess is that this would have higher COSTS for existing code.
>
Which costs do you mean? Could you give an example where an vector-based
list would be slower or consume more space than a linked list?
>> - The _amortized_ computational complexity is O(1) for
>> adding/removing/taking a remainder no matter if it is done from the
>> beginning or from the end of the list.
>>
> We can get that with a pair of singly linked lists right now.
>
Of course, you can emulate almost everything. It's just not too much
convenient.
>> - It takes O(1) time to find out the size of the list.
>>
> It is amazing just how seldom this is interesting.
>
Sure it is. But if you can get it for free, then why not?
>> - Cache-hits ratio is seriously improved as the list is located in a
>> single chunk of memory.
>>
> You are assuming that the list *elements* are not scattered all over
> the place. There seems to be no reason to believe that (except for
> strings). If you are mapping along a list doing some computation that
> produces a new result, e.g.,
> zip([X|Xs], [Y|Ys]) -> [{X,Y}|zip(Xs, Ys)];
> zip(_, _) -> [].
> the present scheme tends to put the list cell near the newly created
> element it points to. (If we ran heaps DOWN instead of up, the list
> cell would precede the element, which would be perfect for a cache.
> That's an experiment someone should try some day.) Your proposal
> would put a list element and the cell that points to it far apart,
> which is bad for the cache.
>
I might be missing something. However, I don't think it matters if the
cells and elements are close to each other. There are different
architectures of CPU caches, however I do not remember any modern one
which would map, say, the whole 2M of cache to a flat block of memory.
Instead, the cache is a number of cells, each of them maps to its small
piece of memory. As a result, both current implementation and the one
with cells and elements grouped into lines apart would have similar
performance while zipping.
>> A few words regarding the implementation:
>> If you take a look at Java LinkedList and ArrayList, the ArrayList is
>> generally 3 times faster.
>>
>
> Yes, but that's not really comparable.
> A Java LinkedList is a record containing a stored size (this is one of
> the things you are arguing FOR) and a pointer to a DOUBLY linked list.
> An Entry<E> has to be at least 4 words and could be 6 depending on the
> Java implementation. Oh yes, it's a doubly linked list with a header,
> so a completely empty Java LinkedList starts out holding at least as
> much space as an Erlang list with 4 elements. Adding a single new
> element
> at the front
> (a) is destructive, unlike Erlang
> (b) has to initialise at least four words of memory,
> has to change two existing pointers, and
> has to increment two counters.
> An Erlang cons just has to initialise two words of memory.
>
> Java's LinkedList is, in short, a textbook example of how *NOT* to do
> linked lists, and if ArrayLists are only 3 times faster, that is a
> really damning criticism of the implementation quality of ArrayList.
>
I understand your dislike to Java, but I think you are too biased
against it. Java lists _are_ mutable. They _do_ allow you to iterate in
both directions. If you can, you can always try to invent a better way
to implement a doubly linked mutable list. But I guess its not easy.
As for a simple immutable linked list, the Erlang version is great.
There is no doubt about it.
By the way, in case you are attentive, you probably noticed that I did
not mean to say that the Java version of LinkedList is a great thing.
What I said is that Java's ArrayList can be an example of a vector-based
list, nothing more. And of course, a much better thing can be
implemented for a purely functional language.
> --- Idea #3:
>
>> "Typed lists"
>>
>> Both kinds of list implementations can benefit from knowing what
>> type of
>> data is going to be stored in them. It would lead to a decrease in the
>> consumed space and improved performance.
>>
>> It is possible to implement a "general" kind of list which can hold
>> anything plus some specific implementations for storing 8bit and 16bit
>> values.
>>
>
> The NuProlog implementation of Prolog from the University of Melbourne
> did this. I've spoken in person with the guy who implemented that, and
> he said it was a big headache and if they were doing it all again that's
> one hack they would never ever try again. Again a data point:
> Interlisp-D
> handled strings as packed arrays of bytes (or packed arrays of 16-bit
> codes)
> and had special microcode support for them. Xerox Quintus Prolog,
> running
> on the same hardware, in the Interlisp environment, used ordinary Prolog
> list cells (just like Erlang ones). Guess which one was faster at
> string
> manipulation?
>
Yes, I heard such stories. Are you sure they have implemented that
_properly_? I mean, not just like endless runtime checks for type and
all such horrid stuff. I mean an implementation were all possible
conversions and type checks are eliminated. For some reason, I am sure
they did not do that. :-)
You might want to look at modern implementations of Common LISP, for
instance. They do such kind of job nicely. Also, you can for instance
compare Erlang HIPE to SBCL on http://shootout.alioth.debian.org/. The
only test case where Erlang wins is a cheap concurrency. Do you think it
is a coincidence? Take a look at "reverse-complement" for example. What
is so special in SBCL Lisp that it is 50 times faster and consume 12
times less memory? I do not know the answer, but I guess it is because
it can do much more when analyzing the bytecode.
I do not want to say that SBCL Lisp is superior to Erlang. No way! I
just want to bring your attention to the fact, that there are approaches
in implementation of VM which can be considered valuable for
experimenting with.
The bottom line is:
I believe there are some ways which can be probed to improve Erlang
performance. I do not say that they surely will give you a boost. They
are just some things that can be tried.
And two more points:
- I do not see any easy way to try it except for deviating from the
standard and creating a different implementation of VM and some basic
libraries.
- Perhaps everybody is happy about the speed, so let's just forget about it.
Regards,
Denys Rtveliashvili
More information about the erlang-questions
mailing list