Erlang: Using the timer:tc function in escripts

Both escripts and timer:tc features of Erlang are very useful for writing simple test code to profile functions.

There is one tiny issue with using timer:tc/1 or timer:tc/2 from within escripts though: they will not work in the interpreted execution mode.

For example, you may have an escript such as below:

#!/usr/bin/env escript
-module(test).

-export([generate_list/1]).

generate_list(N) ->
  lists:seq(1, N).

main(_) ->
  io:format("time: ~p~n", [timer:tc(generate_list, [1000])]).

Running this with “escript test.erl” would yield an error:

escript: exception error: undefined function test:generate_list/1
  in function  timer:tc/2 (timer.erl, line 179)

The issue is that the default escript mode is “interpreted” and not “compiled”. This leads to it not finding the function at all.

To fix the execution, one has to add the “-mode(compile).” line to the script, and also use the timer:tc/3 form of execution instead of the timer:tc/1 or timer:tc/2.

A fixed script of the above example would thus be:

#!/usr/bin/env escript
-mode(compile).

-module(test).

-export([generate_list/1]).

generate_list(N) ->
  lists:seq(1, N).

main(_) ->
  io:format("time: ~p~n", [timer:tc(?MODULE, generate_list, [1000])]).

I think the same should hold for apply calls too, or any function that uses the Module-Function-Arguments style of dynamic calls.

Published by

Harsh

Harsh, also known to some as 'Qwerty' or 'QwertyManiac' online, is a Customer Operations Engineer at Cloudera, Inc.. Harsh is a fan of trance and electronic music, distributed systems and GUI programming, and loves to troubleshoot and hack on code in his free time. Formerly a KDE committer, he now is a committer on the Apache Hadoop and Apache Oozie projects and is a great fan of all Open Source Software.