Time a function
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Write a program which uses a timer (with the least granularity available on your system) to time how long a function takes to execute.
This task is intended as a subtask for Measure relative performance of sorting algorithms implementations.
Ada
with Ada.Calendar; use Ada.Calendar; with Ada.Text_Io; use Ada.Text_Io; procedure Query_Performance is type Proc_Access is access procedure(X : in out Integer); function Time_It(Action : Proc_Access; Arg : Integer) return Duration is Start_Time : Time := Clock; Finis_Time : Time; Func_Arg : Integer := Arg; begin Action(Func_Arg); Finis_Time := Clock; return Finis_Time - Start_Time; end Time_It; procedure Identity(X : in out Integer) is begin X := X; end Identity; procedure Sum (Num : in out Integer) is begin for I in 1..1000 loop Num := Num + I; end loop; end Sum; Id_Access : Proc_Access := Identity'access; Sum_Access : Proc_Access := Sum'access; begin Put_Line("Identity(4) takes" & Duration'Image(Time_It(Id_Access, 4)) & " seconds."); Put_Line("Sum(4) takes:" & Duration'Image(Time_It(Sum_Access, 4)) & " seconds."); end Query_Performance;
Example
Identity(4) takes 0.000001117 seconds. Sum(4) takes: 0.000003632 seconds.
C++
<cpp>#include <ctime>
- include <iostream>
using namespace std;
int identity(int x) { return x; } int sum(int num) {
for (int i = 0; i < 1000000; i++) num += i; return num;
}
double time_it(int (*action)(int), int arg) {
clock_t start_time = clock(); action(arg); clock_t finis_time = clock(); return ((double) (finis_time - start_time)) / CLOCKS_PER_SEC;
}
int main() {
cout << "Identity(4) takes " << time_it(identity, 4) << " seconds." << endl; cout << "Sum(4) takes " << time_it(sum, 4) << " seconds." << endl; return 0;
}</cpp>
Example
Identity(4) takes 0 seconds. Sum(4) takes 0.01 seconds.
Common Lisp
Common Lisp provides a standard utility for performance measurement, time:
CL-USER> (time (reduce #'+ (make-list 100000 :initial-element 1))) Evaluation took: 0.151 seconds of real time 0.019035 seconds of user run time 0.01807 seconds of system run time 0 calls to %EVAL 0 page faults and 2,400,256 bytes consed.
(The example output here is from SBCL.)
However, it merely prints textual information to trace output, so the information is not readily available for further processing (except by parsing it in a CL-implementation-specific manner).
The functions get-internal-run-time and get-internal-real-time may be used to get time information programmatically, with at least one-second granularity (and usually more). Here is a function which uses them to measure the time taken for one execution of a provided function:
(defun timings (function) (let ((real-base (get-internal-real-time)) (run-base (get-internal-run-time))) (funcall function) (values (/ (- (get-internal-real-time) real-base) internal-time-units-per-second) (/ (- (get-internal-run-time) run-base) internal-time-units-per-second))))
CL-USER> (timings (lambda () (reduce #'+ (make-list 100000 :initial-element 1)))) 17/500 7/250
Forth
: time: ( "word" -- ) utime 2>R ' EXECUTE utime 2R> D- <# # # # # # # [CHAR] . HOLD #S #> TYPE ." seconds" ;
1000 time: MS ; 1.000081 seconds ok
Haskell
import System.CPUTime -- We assume the function we are timing is an IO monad computation timeIt :: (Fractional c) => (a -> IO b) -> a -> IO c timeIt action arg = do startTime <- getCPUTime action arg finishTime <- getCPUTime return $ fromIntegral (finishTime - startTime) / 1000000000000 -- Version for use with evaluating regular non-monadic functions timeIt' :: (Fractional c) => (a -> b) -> a -> IO c timeIt' f = timeIt (\x -> f x `seq` return ())
Example
*Main> :m + Text.Printf Data.List *Main Data.List Text.Printf> timeIt' id 4 >>= printf "Identity(4) takes %f seconds.\n" Identity(4) takes 0.0 seconds. *Main Data.List Text.Printf> timeIt' (\x -> foldl' (+) x [1..1000000]) 4 >>= printf "Sum(4) takes %f seconds.\n" Sum(4) takes 0.248015 seconds.
J
Time and space requirements are tested using verbs obtained through the Foreign conjunction (!:). 6!:2 returns time required for execution, in floating-point measurement of seconds. 7!:2 returns a measurement of space required to execute. Both receive as input a sentence for execution.
When the Memoize feature or similar techniques are used, execution time and space can both be affected by prior calculations.
Example
(6!:2,7!:2) '|: 50 50 50 $ i. 50^3' 0.00387912 1.57414e6
Java
<java>public class TimeIt { public static void main(String[] args){ long start, end; start = System.currentTimeMillis(); countTo(100000000); end = System.currentTimeMillis(); System.out.println("Counting to 100000000 takes "+(end-start)+"ms"); start = System.currentTimeMillis(); countTo(1000000000L); end = System.currentTimeMillis(); System.out.println("Counting to 1000000000 takes "+(end-start)+"ms");
}
public static void countTo(long x){ System.out.println("Counting..."); for(long i=0;i<x;i++); System.out.println("Done!"); } }</java> Output:
Counting... Done! Counting to 100000000 takes 375ms Counting... Done! Counting to 1000000000 takes 3625ms
OCaml
<ocaml>let time_it action arg =
let start_time = Sys.time () in ignore (action arg); let finish_time = Sys.time () in finish_time -. start_time</ocaml>
Example
# Printf.printf "Identity(4) takes %f seconds.\n" (time_it (fun x -> x) 4);; Identity(4) takes 0.000000 seconds. - : unit = () # let sum x = let num = ref x in for i = 0 to 999999 do num := !num + i done; !num;; val sum : int -> int = <fun> # Printf.printf "Sum(4) takes %f seconds.\n" (time_it sum 4);; Sum(4) takes 0.084005 seconds. - : unit = ()
Python
Given function and arguments return a time (in microseconds) it takes to make the call.
Note: There is an overhead in executing a function that does nothing. <python>import sys, timeit def usec(function, arguments):
modname, funcname = __name__, function.__name__ timer = timeit.Timer(stmt='%(funcname)s(*args)' % vars(), setup='from %(modname)s import %(funcname)s; args=%(arguments)r' % vars()) try: t, N = 0, 1 while t < 0.2: t = min(timer.repeat(repeat=3, number=N)) N *= 10 microseconds = round(10000000 * t / N, 1) # per loop return microseconds except: timer.print_exc(file=sys.stderr) raise
def nothing(): pass def identity(x): return x</python>
Example
>>> print usec(nothing, []) 1.7 >>> print usec(identity, [1]) 2.2 >>> print usec(pow, (2, 100)) 3.3 >>> print map(lambda n: str(usec(qsort, (range(n),))), range(10)) ['2.7', '2.8', '31.4', '38.1', '58.0', '76.2', '100.5', '130.0', '149.3', '180.0']
using qsort() from Quicksort. Timings show that the implementation of qsort() has quadratic dependence on sequence length N for already sorted sequences (instead of O(N*log(N)) in average).