Function frequency: Difference between revisions

(Added Julia language)
Line 1,152:
infix:<..>
infix:<-></pre>
 
=={{header|Phix}}==
As Phix is self hosted, we can modify the compiler (or a copy of it) directly for this task.<br>
Add the line shown to procedure Call() in pmain.e, after the else on line 4938 (at the time of writing)
<pre>
else -- rType=FUNC|TYPE
log_function_call(rtnNo)
</pre>
Now create our test.exw program, which wraps the entire compiler:
<lang Phix>constant func_log = new_dict(),
func_freq = new_dict()
 
global procedure log_function_call(integer rtnNo)
integer node = getd_index(rtnNo,func_log)
setd(rtnNo,iff(node=NULL?1:getd_by_index(node,func_log)+1),func_log)
end procedure
 
include p.exw -- the phix compiler, full source
 
-- invert the dictionary, then print top ten
 
integer count = 0
function visitor(object key, integer data, integer user_data)
if user_data=1 then -- invert
setd({data,key},0,func_freq)
else
key[2] = symtab[key[2]][S_Name]
?key
count += 1
if count>10 then return 0 end if -- cease traversal
end if
return 1
end function
constant r_visitor = routine_id("visitor")
 
rebuild_callback() -- (convert ternary tree indexes to readable names)
 
traverse_dict(r_visitor,1,func_log) -- invert
traverse_dict(r_visitor,2,func_freq,rev:=true) -- top 10</lang>
Invoke using "p test -norun test" (note you can omit the ".exw" part of "test.exw")
 
Notes:<br>
The log_function call is passed an index into the symbol table.<br>
For performance reasons the compiler uses integer indexes, so we need to invoke
rebuild_callback() to replace them with human-readable names in the symbol table.<br>
For more details of S_Name and other constants/contents of the symbol table, see pglobals.e<br>
The compiler (p.exe) interprets test.exw(+p.exw) which compiles a third copy of itself under -norun.<br>
Notice that it is not necessary to compile the compiler (using p -c p) to test changes in it, and in
fact weeks or months of work on the compiler often happens purely in interpreter mode, between actually
creating a new executable.<br>
If, instead, you want to know how many times a function is called at run-time, just add "with profile"
to the source and it will create a ex.pro listing which tells you.
 
Lastly, remember to remove/comment out that log_function_call() in pmain.e
{{out}}
<pre>
{1253,"length"}
{655,"and_bits"}
{354,"append"}
{308,"find"}
{163,"or_bits"}
{158,"repeat"}
{154,"SetField"}
{136,"sprintf"}
{119,"equal"}
{105,"sequence"}
{90,"platform"}
</pre>
 
=={{header|PicoLisp}}==
7,795

edits