aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorJosé Valim <[email protected]>2016-02-01 10:50:32 +0100
committerJosé Valim <[email protected]>2016-02-15 10:53:05 +0100
commitbc1e16e334afc8255b221e3ffbb6f7c54fb91a2d (patch)
tree5baa13ffe9a1727e66e4fcd48dda1521cf94dd9e /erts/emulator/beam/beam_emu.c
parente038cbe699acc19901e10b9569a3b783e900582d (diff)
downloadotp-bc1e16e334afc8255b221e3ffbb6f7c54fb91a2d.tar.gz
otp-bc1e16e334afc8255b221e3ffbb6f7c54fb91a2d.tar.bz2
otp-bc1e16e334afc8255b221e3ffbb6f7c54fb91a2d.zip
Avoid erts_cmp jump in atom, int and float comparisons
Given the function definition below: check(X) when X >= 0, X <= 20 -> true. @nox has originally noticed that perfoming lt and ge guard tests were performing slower than they should be. Further investigation revealed that most of the cost was in jumping to the erts_cmp function. This patch brings the operations already inlined in erts_cmp into the emulator, removing the jump cost. After applying these changes, invoking the check/1 function defined above 30000 times with different values from 0 to 20 has fallen from 367us to 213us (measured as average of 3 runs). This is a considerably improvement over Erlang 18 which takes 556us on average. Floats have also dropped their time from 1126us (on Erlang 18) to 613us.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 4d7b00b032..659ff3ad2f 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -718,10 +718,10 @@ void** beam_ops;
#define NotEqualImmed(X, Y, Action) if (X == Y) { Action; }
#define EqualExact(X, Y, Action) if (!EQ(X,Y)) { Action; }
#define NotEqualExact(X, Y, Action) if (EQ(X,Y)) { Action; }
-#define Equal(X, Y, Action) if (!CMP_EQ(X,Y)) { Action; }
-#define NotEqual(X, Y, Action) if (!CMP_NE(X,Y)) { Action; }
-#define IsLessThan(X, Y, Action) if (CMP_GE(X, Y)) { Action; }
-#define IsGreaterEqual(X, Y, Action) if (CMP_LT(X, Y)) { Action; }
+#define Equal(X, Y, Action) CMP_EQ_ACTION(X,Y,Action)
+#define NotEqual(X, Y, Action) CMP_NE_ACTION(X,Y,Action)
+#define IsLessThan(X, Y, Action) CMP_LT_ACTION(X,Y,Action)
+#define IsGreaterEqual(X, Y, Action) CMP_GE_ACTION(X,Y,Action)
#define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; }