[erlang-questions] Floor Function?

Ulf Wiger ulf.wiger@REDACTED
Mon Mar 16 15:08:54 CET 2009


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 ...

Neither have I, but given ROK's track record of working on
language implementations, it would surprise me if he
didn't have a pretty good intuition on the subject. ;-)

However, looking at the source:

Compare (X-T):

#define MY_IS_SSMALL(x) (((Uint) (((x) >> (SMALL_BITS-1)) + 1)) < 2)

  OpCase(i_minus_jId):
  {
      Eterm result;

      if (is_both_small(tmp_arg1, tmp_arg2)) {
          Sint i = signed_val(tmp_arg1) - signed_val(tmp_arg2);
          ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
          if (MY_IS_SSMALL(i)) {
              result = make_small(i);
              STORE_ARITH_RESULT(result);
          }
      }
      arith_func = ARITH_FUNC(mixed_minus);
      goto do_big_arith2;
  }

do_big_arith2:
  {
      Eterm result;
      Uint live = Arg(1);

      SWAPOUT;
      reg[0] = r(0);
      reg[live] = tmp_arg1;
      reg[live+1] = tmp_arg2;
      result = arith_func(c_p, reg, live);
      r(0) = reg[0];
      SWAPIN;
      ERTS_HOLE_CHECK(c_p);
      if (is_value(result)) {
          STORE_ARITH_RESULT(result);
      }
      goto lb_Cl_error;
  }


against (X<T):

#define CMP_LT(a,b)     ((a) != (b) && cmp_lt((a),(b)))
#define cmp_lt(a,b)     (cmp((a),(b)) < 0)

Sint
cmp(Eterm a, Eterm b)
{
     ...
     if (a == b) {       /* Equal values or pointers. */
         return 0;
     }

     /* deal with majority (?) cases by brute-force */
     if (is_atom(a)) {
         if (is_atom(b))
             return cmp_atoms(a, b);
     } else if (is_both_small(a, b)) {
         return signed_val(a) - signed_val(b);
     }
     ...


I think we can safely say that (X<T) is cheaper than
(X-T), but whether there's a big difference? You'll
probably have to run quite a few iterations to see
a significant difference, since both operations are
very cheap.

The basic rule of thumb is that the VM knows what type
a comparison operation will have, while an arithmetic
operation may result in a bignum, so there has to be
checking of the output type.

The above source was taken from the R13A snapshot,
files beam_emu.c, erl_bif_op.c, erl_term.h, global.h

BR,
Ulf W
-- 
Ulf Wiger
CTO, Erlang Training & Consulting Ltd
http://www.erlang-consulting.com



More information about the erlang-questions mailing list