[erlang-questions] Floor Function?

David Mercer <>
Mon Mar 16 16:11:22 CET 2009


On 3/16, Hynek Vychodil wrote:

 

Are you sure that there is big difference between compute X-T and decide X<T
or which one is less expensive? I'm not! If you haven't measured ...

 

For what it's worth, I timed them, and ROK's is about 40-50% faster.  That
being said, my question was related more to whether I was lacking in my
documentation-searching abilities rather than to any difficulty in writing a
floor function.  However, as an Erlang hobbyist, I enjoyed the exercise in
timing, and completely overengineered my test harness for your pleasure.
Here's my code, in case you spot some error and so want to appeal my
conclusions:

 

> floor:test(10000000).

[{ippolito,[{runtime,17766},

            {wall_clock,17782},

            {runtime_speed_vs_okeefe,0.6877181132500282}]},

 {okeefe,[{runtime,12218},

          {wall_clock,12218},

          {runtime_speed_vs_ippolito,1.454084138156818}]}]

 

-module(floor).

 

-export([ippolito/1, okeefe/1]).

-spec ippolito(float()) -> integer().

-spec okeefe  (float()) -> integer().

 

-export([test/1]).

-spec test(non_neg_integer()) -> term().

 

 

ippolito(X) ->

    T = trunc(X),

    case (X - T) of

        Neg when Neg < 0 -> T - 1;

        Pos when Pos > 0 -> T;

        _ -> T

    end.

 

 

okeefe(X) ->

     T = trunc(X),

     if X < T -> T - 1

      ; true  -> T

     end.

 

 

test(N) ->

    Tests = [{ippolito, fun ippolito/1}, {okeefe, fun okeefe/1}],

    Results = [ {Name, test(F, N)} || {Name, F} <- Tests ],

    _Report = lists:map(add_comparisons_to_others(Results), Results).

 

 

test(F, N) ->

    Args = [-4.0, -2.75, -1.5, -0.1, 0.0, 1.1, 2.5, 3.75, 4.0],

 

    % Check to make sure results are accurate

    ResultsAreAccurate = lists:seq(-4, 4) == [F(X) || X <- Args],

    if ResultsAreAccurate -> ok end,

 

    Fun = fun() -> lists:foreach(F, Args) end,

 

    statistics(runtime),

    statistics(wall_clock),

    repeat(N, Fun),

    {_, RunTime} = statistics(runtime),

    {_, WallClockTime} = statistics(wall_clock),

 

    [ {runtime, RunTime}, {wall_clock, WallClockTime}].

 

 

repeat(0, _F) -> ok;

repeat(N, F) -> F(), repeat(N - 1, F).

 

 

filter_out(Name) ->

    fun

        ({OtherName, _}) when OtherName == Name -> false;

        (_) -> true

    end.

 

 

filter_out(Name, List) -> lists:filter(filter_out(Name), List).

 

 

add_comparisons_to_others(FullResults) ->

    fun({Name, Stats}) ->

        Others = filter_out(Name, FullResults),

        RunTime = proplists:get_value(runtime, Stats),

        Comparisons =

            [ {list_to_atom("runtime_speed_vs_" ++ atom_to_list(OtherName)),
SpeedComparison}

                || {OtherName, OtherStats} <- Others

                 , OtherRunTime <- [proplists:get_value(runtime,
OtherStats)]

                 , SpeedComparison <- [OtherRunTime / RunTime]

            ],

        {Name, Stats ++ Comparisons}

    end.

 

Cheers,

 

David

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090316/77f5bd63/attachment.html>


More information about the erlang-questions mailing list