1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192(*****************************************************************************
Liquidsoap, a programmable audio stream generator.
Copyright 2003-2023 Savonet team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details, fully stated in the COPYING
file at the root of the liquidsoap distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************)(** Function call information. *)typet={total_time:float;(** Time spent in the function. *)self_time:float;(** Time spent in the function excluding children. *)}letcalls=ref[](* Call stack. *)letstack=ref[](* Time spent in children. *)letchildren=ref[ref0.](** Indicate the time spent in a given function. *)letaddft=calls:=(f,t)::!calls(** Measure time for a given function. *)lettimefnamefx=stack:=fname::!stack;children:=ref0.::!children;lett0=Unix.gettimeofday()inletans=fxinlett1=Unix.gettimeofday()instack:=List.tl!stack;letchildren_time=!(List.hd!children)inchildren:=List.tl!children;letdt=t1-.t0inList.hd!children:=!(List.hd!children)+.dt;(* TODO: time is counted multiple times in recursive calls. *)lettotal_time=dtinletself_time=dt-.children_timeinlett={total_time;self_time}inaddfnamet;ansmoduleM=Map.Make(structtypet=stringletcompare=compareend)letstats()=letm=refM.emptyinList.iter(fun(f,t)->m:=M.updatef(functionSomel->Some(t::l)|None->Some[t])!m)!calls;letm=!minletl=M.bindingsminletl=List.map(fun(f,t)->(f,(List.fold_left(funxt->x+.t.self_time)0.t,List.fold_left(funxt->x+.t.total_time)0.t,List.lengtht)))linletl=List.sort(fun(_,t)(_,t')->-comparett')linletl=List.map(fun(f,(self,total,n))->[|f;string_of_floatself;string_of_floattotal;string_of_intn|])linletl=[|"function";"self";"total";"calls"|]::[||]::linletl=Array.of_listlinLang_string.string_of_matrixl