Skip to content

Instantly share code, notes, and snippets.

@slfritchie
Forked from davisp/shell_test.erl
Created November 21, 2012 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slfritchie/4122476 to your computer and use it in GitHub Desktop.
Save slfritchie/4122476 to your computer and use it in GitHub Desktop.
Experimenting with selective receive optimization
ref2_test() ->
Ref = make_ref(),
ref_fixed(Ref),
receive Ref -> Ref after 500 -> bummer end.
% With R15B02, yes, this one is slower.
% No, removing the 'after' clause doesn't matter.
ref2_test_with_ok_match() ->
Ref = make_ref(),
ok = ref_fixed(Ref),
receive Ref -> Ref after 500 -> bummer end.
/* This one works as expected with R14B04, R15B01, and R15B02 */
static ERL_NIF_TERM
repeat_fixed(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifEnv* msg_env = enif_alloc_env();
ERL_NIF_TERM msg;
ErlNifPid pid;
enif_self(env, &pid);
msg = enif_make_copy(msg_env, argv[0]);
enif_send(env, &pid, msg_env, msg);
enif_free_env(msg_env);
return ATOM_OK;
}
static ErlNifFunc nif_funcs[] = {
{"ref_fixed", 1, repeat_fixed}
};
LoadQueue = fun(N) ->
lists:foreach(fun(_) ->
self() ! foo
end, lists:seq(1, N))
end.
RunTest = fun() ->
lists:foreach(fun(_) ->
Ref = termsend:ref(),
receive Ref -> ok end
end, lists:seq(1, 10000))
end.
RunTest(). % This is ~instant
LoadQueue(10000).
RunTest(). % This is ~30-60s
#include "erl_nif.h"
static ERL_NIF_TERM
repeat(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifEnv* msg_env = enif_alloc_env();
ERL_NIF_TERM ref = enif_make_ref(env);
ERL_NIF_TERM msg = enif_make_copy(msg_env, ref);
ErlNifPid pid;
enif_self(env, &pid);
enif_send(env, &pid, msg_env, msg);
enif_free_env(msg_env);
return ref;
}
static ErlNifFunc nif_funcs[] = {
{"ref", 0, repeat}
};
ERL_NIF_INIT(termsend, nif_funcs, NULL, NULL, NULL, NULL);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment