[erlang-questions] Erlang arithmetics
Dmitry Demeshchuk
demeshchuk@REDACTED
Sat Oct 30 14:23:42 CEST 2010
On Sat, Oct 30, 2010 at 12:52 PM, Morten Krogh <mk@REDACTED> 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-unsubscribe@REDACTED
>
>
--
Best regards,
Dmitry Demeshchuk
More information about the erlang-questions
mailing list