[erlang-questions] Feedback for my first non-trivial Erlang program

Technion technion@REDACTED
Tue Dec 15 11:47:26 CET 2015


I'd like to continue this thread by discussing benchmarks. It's important to work out what optimisations help, and which don't. timer:tc/1 is useful for this. I've run this work some test values here. It's interesting that the time taken increases at much more than a linear rate.

8> timer:tc(pension2, totalBalance, [10]).
{30,30565.063527483566}
9> timer:tc(pension2, totalBalance, [20]).
{81,41736.17177446989}
12> timer:tc(pension2, totalBalance, [60]).
{840,93052.91160889174}
13> timer:tc(pension2, totalBalance, [70]).
{559006,73294.80080230196}

At 75, it ran so long I killed it.

With that said, here is the some of the same bechmarks, after applying zxq9's tail call optimisation.

18> timer:tc(pension2, totalBalance, [10]).
{28,30565.063527483566}
20> timer:tc(pension2, totalBalance, [30]).
{141,53541.01834136172}
21> timer:tc(pension2, totalBalance, [60]).
{823,93052.91160889175}
22> timer:tc(pension2, totalBalance, [70]).
{562409,73294.80080230198}

So there is definitely a measureable improvement there. 

You can also write tradingFees in a way that helps recursion, as investments/1 seems to be the bulk of the work:

 tradingFees(T) ->
 X = case working(T) of
 true -> transactionFee();
 false -> tax(expenses(T),T) + transactionFee()
 end,
 X + investments(T).

Further improvements noted (slight):
24> timer:tc(pension2, totalBalance, [10]).
{26,30565.063527483566}
28> timer:tc(pension2, totalBalance, [70]).
{560813,73294.80080230198}

I don't understand what happened with remove/1, but the optimised solution seemed to slow things down in the high cases, but had notable improvements at the low end:

37> timer:tc(pension2, totalBalance, [10]).
{28,30565.063527483566}
41> timer:tc(pension2, totalBalance, [30]).
{246,53541.01834136172}
39> timer:tc(pension2, totalBalance, [60]).
{701,93052.91160889175}
38> timer:tc(pension2, totalBalance, [70]).
{581899,73294.80080230198}

All in all, there's a number of optimisations to be made, but I can see using this app with an input > 100 to still be painful. Is this algorithm documented in any other language anywhere? I'm curious as to whether there's a bigger picture being missed here.

I would also propose - writing some unit tests. It would be disastrous to "optimise" this code in such a way that the output changes. A few unit tests should address that.

Finally, I would like to suggest using github gists for this much code. Copy+pasting it from email lost most of the formatting and made it painful to read/manipulate.



More information about the erlang-questions mailing list