From: Nicolas M. T. <nt...@us...> - 2005-02-15 14:35:44
|
Update of /cvsroot/mupad-combinat/MuPAD-Combinat/lib/PROG In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18147 Modified Files: timeThis.mu Log Message: New function: prog::timeThese. Improvements to prog::timeThis. Index: timeThis.mu =================================================================== RCS file: /cvsroot/mupad-combinat/MuPAD-Combinat/lib/PROG/timeThis.mu,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** timeThis.mu 14 Feb 2005 16:18:18 -0000 1.1 --- timeThis.mu 15 Feb 2005 14:35:35 -0000 1.2 *************** *** 9,32 **** *****************************************************************************/ prog::timeThis := ! proc(count: Type::NonNegInt, expression) : DOM_FLOAT option hold; ! local before, after, emptyLoopTime, msPerCall; begin // Timing the empty loop ! before := time(): ! for i from 1 to count do ! context(NIL); ! end_for; ! after := time(); ! emptyLoopTime := after-before; ! ! before := time(): ! for i from 1 to count do ! context(expression); end_for; ! after := time(); ! msPerCall := float((after-before - emptyLoopTime) / count); ! fprint(Unquoted, 0, expr2text(msPerCall) ." ms/call"); ! msPerCall; end_proc: --- 9,85 ---- *****************************************************************************/ + // timeIt(count, expression): + // + // Evaluates 'expression' in the caller's caller's context 'count' times, + // and returns a list containing: + // - CPU time used for 'count' executions of expression + // - real time used for 'count' executions of expression + // + // Problem: a function can't right away evaluate an expression in + // one's caller's caller's context. + // + // Workaround: we use an alias to build an "inline function" + // + // Caveat: The first local variables of the calling procedure should + // *exactly* match the local variables used in timeIt! This makes + // in particular some assumptions in the order in which MuPAD + // order the variables internally. + + proc() + local before, rbefore, i; + begin + alias(timeIt(count, expression) = + (before := time(): + rbefore := rtime(): + for i from 1 to count do + context(expression); + end_for; + [time()-before, rtime()-rbefore])); + end_proc(): + + prog::timeString := + proc(count: Type::NonNegInt, cpu: Type::Real, real: Type::Real) : DOM_STRING + begin + cpuPerCall := float(cpu / count); + realPerCall := float(real / count); + "CPU: " . expr2text(cpuPerCall) . " ms/call " . + "Wallclock: " . expr2text(cpuPerCall) . " ms/call"; + end_proc: + prog::timeThis := ! proc(count: Type::NonNegInt, expression) : DOM_NULL option hold; ! local before, rbefore, i, // for timeIt ! cpu, real, cpuEmpty, realEmpty, emptyExpression; begin + count := context(count); // Timing the empty loop ! emptyExpression := NIL; ! [cpuEmpty, realEmpty] := timeIt(count, emptyExpression); ! // Timing the expression ! [cpu, real] := timeIt(count, expression); ! fprint(Unquoted, 0, ! prog::timeString(count, cpu-cpuEmpty, real-realEmpty)); ! null(); ! end_proc: ! ! prog::timeThese := ! proc(count: Type::NonNegInt, expressions) : DOM_NULL ! option hold; ! local before, rbefore, i, // for timeIt ! cpu, real, cpuEmpty, realEmpty, emptyExpression, ! eq; ! begin ! count := context(count); ! // Timing the empty loop ! emptyExpression := NIL; ! [cpuEmpty, realEmpty] := timeIt(count, emptyExpression); ! // Timing the expressions, one by one ! for eq in expressions do ! [cpu, real] := timeIt(count, op(eq,2)); ! fprint(Unquoted, 0, ! context(op(eq,1)) . ": " . ! prog::timeString(count, cpu-cpuEmpty, real-realEmpty)); end_for; ! null(); end_proc: |