[erlang-questions] Erlang arithmetics

Dmitry Demeshchuk <>
Sat Oct 30 14:48:49 CEST 2010


Hi, Morten

You have a point, random numbers aren't necessary. :) My goal was just
to have some more or less uniform distribution that can be reached
using randomized data. Of course, another variant was to choose some
static arithmetic operation.

To my own defense, I'll say that despite of the random numbers the
results were very similar, so the difference in numbers didn't affect
them much. But still you are right, static numbers are a bit more
reliable.

However, that doesn't answer the question "why so big difference in
speed for the two platforms?". It's well-known that Erlang arithmetics
is slow but I still cannot find a clear answer that describes why
exactly...

Hope, some of Erlang fathers will be able to help with this...

On Sat, Oct 30, 2010 at 4:37 PM, Morten Krogh <> wrote:
> Hi Dimitry
>
> Yes, I first thought that the random number generation was timed as well, so
> some of my points are irrelevant.
>
> But why don't you compare very short programs instead that just loops or
> recurses on the number N?
>
> like this in js:
>
> sum = 0;
> for (i =0; i < 1000000; i++) {
>    sum += 37*i*(i - 5) + i + 23;
> }
>
> and the same in erlang. Do you need the lists of random numbers for your
> basic arithmetic?
>
> Morten.
>
>
> On 10/30/10 2:23 PM, Dmitry Demeshchuk wrote:
>>
>> On Sat, Oct 30, 2010 at 12:52 PM, Morten Krogh<>  wrote:
>>>
>>> Hi Dimitry
>>>
>>> You need to answer a lot of questions before you can even start the
>>> comparison.
>>>
>>> 1. Should the implementations keep a list of all points, or can they just
>>> calculate a running sum and discard the points immediately.
>>> Right now, your erlang solution keeps two lists, and your js program keep
>>> one object (hash table).
>>
>> No, garbage collecting time shouldn't be considered, as well as memory
>> usage. I understand that this isn't very fair (for example, one
>> platform may be much faster on garbage collecting but slower on
>> arithmetic operations) but the purpose of the test is to measure some
>> average productivity of basic arithmetic operations.
>>
>>> 2. Is parallelizing the computation allowed?. If so, this would give
>>> erlang
>>> an edge since you can parallelize this problem by simple message passing.
>>> That would require more work in js.
>>
>> No, if I wanted to use it, I would definitely do it. :) But, first of
>> all, Node.js will have a significant overhead on IPC (to run
>> multi-core task you'll have to run several processes and communicate
>> between them). And, that is also important, my goal was to compare
>> arithmetics abilities, not abilities of parallelizing (where Node will
>> be extremely slower).
>>
>>> 3. What types do you want for the points. In erlang you use
>>> random:uniform(1000) which returns integers, in js Math.random() which
>>> returns floats.
>>>    The type issue also includes the question of checking for overflow, as
>>> you mention.
>>
>> Well, that's why I used Math.floor for JS ;)
>>
>>> 4. Should the program be short and simple?  In the extreme case, the
>>> erlang
>>> program could use nifs.
>>
>> Sure, I could use a port or even a driver. But the subject of interest
>> is Erlang built-in arithmetics, not C. In my article, I mention that
>> ports can be used for some expensive operations, but these
>> calculations will be limited by the port itself then Erlang
>> performance.
>>
>>> 5. How should they calculate random numbers? There could be a huge
>>> difference in speed based on the algorithm of course.
>>>    Actually, I think a speed test between languages should not involve
>>> random numbers, unless you make sure they use the same random number
>>> generating algorithm.
>>
>> As you can see, my tests don't measure random numbers generation time.
>> Yes, I was going to try using the same pseudo-random generation
>> algorithm on both platforms for another test (Erlang will use process
>> dictionary for this, which should slow down the randomizer) but,
>> again, my subject there is just arithmetic operations.
>>
>>> Cheers,
>>>
>>> Morten.
>>>
>>>
>>>
>>>
>>>
>>> On 10/30/10 10:03 AM, Dmitry Demeshchuk wrote:
>>>>
>>>> Greetings.
>>>>
>>>> I'm writing an article comparing Erlang and Node.js and I stumbled
>>>> upon the performance question.
>>>>
>>>> My initial goal was to compare some basic arithmetics speed, like the
>>>> total distance between randomly distributed points. So, I have written
>>>> the following code for Erlang:
>>>>
>>>> =====================================================
>>>>
>>>> -module(arith_speed).
>>>> -export([
>>>>     test/1
>>>> ]).
>>>>
>>>> test(N) ->
>>>>     L = lists:seq(1, N),
>>>>     [{X0, Y0} | Points] = [{random:uniform(1000),
>>>> random:uniform(1000)} || _<- L],
>>>>     Now = now(),
>>>>     lists:foldl(fun move_to/2, {0, {X0, Y0}}, Points),
>>>>     timer:now_diff(now(), Now).
>>>>
>>>> move_to({X, Y}, {Sum, {X0, Y0}}) ->
>>>>     {Sum + math:sqrt((X - X0) * (X - X0) + (Y - Y0) * (Y - Y0)), {X,
>>>> Y}}.
>>>>
>>>> ======================================================
>>>>
>>>> and the following code for Node.js:
>>>>
>>>> ======================================================
>>>>
>>>> var a = [];
>>>> for(var i = 0; i<    1000000; i++) {
>>>>     a[i] = {};
>>>>     a[i].x = Math.floor(Math.random() * 1000);
>>>>     a[i].y = Math.floor(Math.random() * 1000);
>>>> }
>>>>
>>>> var sum = 0;
>>>>
>>>> var start = (new Date()).valueOf();
>>>>
>>>> for(var i = 1; i<    1000000; i++) {
>>>>     var prev = a[i-1];
>>>>     sum += Math.sqrt((a[i].x - prev.x) * (a[i].x - prev.x) + (a[i].y -
>>>> prev.y) * (a[i].y - prev.y));
>>>> }
>>>>
>>>> var end = (new Date()).valueOf();
>>>>
>>>> console.log(end - start);
>>>>
>>>> ============================================
>>>>
>>>> There was no special tuning for Erlang and Node, both using the latest
>>>> versions.
>>>> But "arith_speed:test(1000000)." from Erlang console and "node
>>>> test.js" have given me very different results: about 413 milliseconds
>>>> for Erlang and 124 milliseconds for Node. So, the difference was about
>>>> 4 times! I tried to change the total number of points, and the overall
>>>> result remained the same.
>>>>
>>>> Both Erlang and V8 (Google's engine that is used by Node) use IEEE
>>>> 754-2008 implementation, so that's not about float type
>>>> representation. So, for now I have several probable explanations:
>>>>
>>>> 1. I've done something wrong and my tests suck (but that may mean that
>>>> the difference in performance may be even more significant)
>>>> 2. Erlang uses type overflow check on each computation to determine if
>>>> it's time to switch from smallint to bigint.
>>>> 3. Some more reasons that I don't know about or don't consider.
>>>>
>>>> Also, I'm still not sure if this kind of test is good for arithmetics
>>>> comparison. On one side, it uses only pretty basic operations
>>>> (summing, multiplying and square root) but on the other side it may
>>>> involve some special computation mechanisms for Erlang that may slow
>>>> it down.
>>>>
>>>> So, any help in this research is very appreciated. I understand that
>>>> this involves another platform too, but since Erlang appeared to be
>>>> slower I want to start from it first.
>>>>
>>>> Thanks in advance.
>>>>
>>>
>>> ________________________________________________________________
>>> erlang-questions (at) erlang.org mailing list.
>>> See http://www.erlang.org/faq.html
>>> To unsubscribe; mailto:
>>>
>>>
>>
>>
>
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:
>
>



-- 
Best regards,
Dmitry Demeshchuk


More information about the erlang-questions mailing list