[erlang-questions] Floor Function?
David Mercer
dmercer@REDACTED
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.htm>
More information about the erlang-questions
mailing list