[erlang-questions] how to do faster integer operations (was: some language changes)
Paul Mineiro
paul-trapexit@REDACTED
Wed Jun 6 11:27:16 CEST 2007
paraphrasing ok <ok@REDACTED>:
[ 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