Query Performance

From Rosetta Code

Jump to: navigation, search

Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.

Code examples should be formatted along the lines of one of the existing prototypes.

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.

Contents

[edit] 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;

[edit] Example

Identity(4) takes 0.000001117 seconds.
Sum(4) takes: 0.000003632 seconds.

[edit] C++

#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;
}

[edit] Example

Identity(4) takes 0 seconds.
Sum(4) takes 0.01 seconds.

[edit] 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

[edit] Forth

Works with: GNU Forth

: time: ( "word" -- )
  utime 2>R ' EXECUTE
  utime 2R> D-
  <# # # # # # # [CHAR] . HOLD #S #> TYPE ."  seconds" ;
1000 time: MS  \ 1.000081 seconds ok

[edit] 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 ())

[edit] 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.

[edit] 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.

[edit] Example

   (6!:2,7!:2) '|: 50 50 50 $ i. 50^3'
0.00387912 1.57414e6

[edit] 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!");
	}
}

Output:

Counting...
Done!
Counting to 100000000 takes 375ms
Counting...
Done!
Counting to 1000000000 takes 3625ms

[edit] 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

[edit] 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 = ()

[edit] 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.

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

[edit] 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).

[edit] UNIX Shell

$ time sleep 1

real    0m1.074s
user    0m0.001s
sys     0m0.006s
Personal tools