[erlang-questions] how to do faster integer operations (was: some language changes)

Paul Mineiro <>
Wed Jun 6 11:27:16 CEST 2007


paraphrasing ok <>:

[ a machine width integer type won't help in Erlang because it's
dynamically typed ... maybe there's another way to speed this up ...
 share the function and we'll see ]

Alright, well, I've isolated a "sufficiently generic" part of the
computation which is still disappointingly slow (attached).  My
machine can do 100K in circa 1s using hipe compilation; the equivalent
C is about 2 orders of magnitude faster.

Thanks for the help,

-- p

p.z. (Sorry unfortunately I was in digest mode so can't figure out how to
reply to the original email, but I've switched out of digest mode for the
future)
-------------- next part --------------
-module(megahash).
-compile (export_all).

%-=====================================================================-
%-                                Public                               -
%-=====================================================================-

shiftAdd (X, A, B, C) when is_integer (X),
                           is_integer (A),
                           is_integer (B),
                           is_integer (C) ->
  ((X bsl 4) + A) bxor (X + B) bxor ((X bsr 5) + C).

bitHash (Order, Z, OrderLoc, HashLoc) when is_integer (Order),
                                           is_integer (Z),
                                           is_integer (OrderLoc),
                                           is_integer (HashLoc) ->
  D0 = 16#9e3779b9,
  D1 = 16#3c6ef372,
  D2 = 16#daa66d2b,
  D3 = 16#78dde6e4,
  D7 = 16#f1bbcdc8,

  Key0 = 16#6f2f7a2d,
  Key1 = 16#1553836a,
  Key2 = 16#6a8a5761,
  Key3 = 16#e7331106,

  Y = Order bsr 5,

  if 
    Y /= OrderLoc ->
      NewOrderLoc = Y,
      YOne = (Y * D7) band 16#FFFFFFFF,

      YTwo = (YOne + shiftAdd (Z, Key2, D0, Key3)) band 16#FFFFFFFF,
      ZOne = (Z + shiftAdd (YTwo, Key0, D1, Key1)) band 16#FFFFFFFF,

      YThree = (YTwo + shiftAdd (ZOne, Key3, D2, Key2)) band 16#FFFFFFFF,
      ZTwo = (ZOne + shiftAdd (YThree, Key1, D3, Key0)) band 16#FFFFFFFF,

      NewHashLoc = (YThree bxor ZTwo) band 16#FFFFFFFF,

      ReturnVal = NewHashLoc band (1 bsl (Order band 16#1f)),

      { ReturnVal, NewOrderLoc, NewHashLoc };

    true ->
      ReturnVal = HashLoc band (1 bsl (Order band 16#1f)),

      { ReturnVal, OrderLoc, HashLoc }
  end.

repeat (_F, 0) -> ok;
repeat (F, N) -> F (), repeat (F, N - 1).

benchmark () ->
  T1 = erlang:now (),
  repeat (fun () -> bitHash (2, 16, 16#FFFFFFFF, 16#FFFFFFFF) end,
          100000),
  T2 = erlang:now (),
  timer:now_diff (T2, T1).


More information about the erlang-questions mailing list