Sei sulla pagina 1di 7

University of Engineering and Technology Lahore

Data Structures and Algorithms


Lab Manual 03: Running Time of Programs

Objective:

The Objective of this Lab is to measure the execution times of different algorithms using C
programming language. A simple piece of code will be used to measure the execution time of an
algorithm with sufficient accuracy. Measuring running time is useful especially in the design and
analysis of Algorithms.

Introduction:

To measure the running time of a piece of code, we need to find the number of clock cycles used by
the processor for processing the instructions constituting the code. For example, if the code utilizes
1000 clock cycles for execution and there are 100 clock cycles per second, the execution time of the
code will be 10s.

Method 1 – Clock

Make a new project on MS Visual studio. Start by making an empty project and then add .c file to the
project and enter the following code in it.

The Description of datatype clock_t and clock() function is given after the code.

Sample Code:

#include <stdio.h>
#include <time.h>

int main() {
clock_t start, end;
int i, j;
int outer_loop = 2100;
int inner_loop = 2000;
double run_time;

start = clock(); //start time

// Any code whose execution time is to be checked comes between the start and
the end time for example:

for (i = 0; i < outer_loop; i++) {


for (j = 0; j < inner_loop; j++)
{
}
}

end = clock(); // end time

run_time = (end - start) / ((double)CLOCKS_PER_SEC);


printf("the run time of code is: %g\n", run_time);

getchar();
return 0;
}
clock_t:

Alias of a fundamental arithmetic type capable of representing clock tick counts. Clock ticks are the
unit of time of a constant but system-specific length, as those returned by function clock().

clock() function:

The function returns the processor time consumed by the program. The value returned is of type
clock_t (clock ticks).

CLOCKS_PER_SEC:

To find time in seconds clock ticks need to be divided by CLOCKS_PER_SEC.

Note:

Compiling the same program for different times might give you a different value. This is due to the
fact that your processor is processing many background applications apart from executing your
program. Due to this the value returned by the above code might be different sometimes.

To mitigate this situation, a simple method is to take average of at least 5 runs.

Compile the same program for five times. Fill out the table below by noting down the execution time
for each run and compute the average.

Execution No. Execution Time (s)


1
2
3
4
5
Average

Vary the outer and inner loop indexes in the code above (pick any value). Observe the change in
execution time and fill the following table:

Execution No. Outer Loop value Inner Loop value Runtime(s)


1
2
3

Modify the above code to print output as:

“The running time of code is ___ seconds and ___ milliseconds”

Method 2 – Query Performance counter

Another way of measuring execution time is using Query Performance Counter. The sample code is
given below.

The descriptions of functions are given after the code.


Sample Code:

#include <stdio.h>
#include <Windows.h>
#include <time.h>

int main() {

LARGE_INTEGER start_time, end_time, elapsed_time, frequency;

int i, j;
int outer_loop = 2100;
int inner_loop = 2000;
double run_time;

QueryPerformanceFrequency(&frequency);

QueryPerformanceCounter(&start_time);
// Any code whose execution time is to be checked comes between the start and
the end time

for (i = 0; i < outer_loop; i++) {


for (j = 0; j < inner_loop; j++)
{
}
}

QueryPerformanceCounter(&end_time);

elapsed_time.QuadPart = end_time.QuadPart - start_time.QuadPart;


run_time = ((double)elapsed_time.QuadPart) / frequency.QuadPart;
printf("the run time of code is: %g\n", run_time);

getchar();
return 0;

QueryPeformanceCounter() this function retrieves the current value of the performance counter. It
gives the number of ticks.

QueryPerformanceFrequency() gives the frequency value (ticks-per-second) , which is used to find


time in seconds by

LARGE_INTEGER structure, is a union that represents a 64-bit signed integer, it has a


LowPart and HighPart and QuadPart as its members. LowPart and HighPart store the low-order and
high-order 32 bits of a 64-bit integer, respectively. Its QuadPart member is just a signed 64-bit integer.
Lab Assignment: Calculate the running times of Maximum Subsequence Sum Algorithms
You will measure the execution times of four algorithms for the maximum sub sequence sum problem.
You will use the two different methods; using clock() and QueryPerformancecounter(), for measuring
the run time of these algorithms.

The code for the maximum sub sequence sum is given at the end of the document.

Task

1. Populate the array with values of your choice


2. Declare array size in following fashion.

Algorithm Array size


N3 50 + your roll no. * 10
N2 500 + your roll no. * 10
NlogN 5000 + your roll no. * 10
N 50000 + your roll no. * 10

3. Fill the following table

Algorithm RunTime Method1 (ms) RunTime Method2 (ms)


N3
N2
NlogN
N
Codes for Maximum Subsequence Sum Problem

#include <stdio.h>

/*Define one of Cubic Algorithm, Quadratic Algorithm, NlogNAlgorithm, or Linear


Algorithm to get
one algorithm compiled*/

#define LinearAlgorithm

#ifdef CubicAlgorithm // N^3 Algorithm


int MaxSubsequenceSum(const int A[], int N)
{
int ThisSum, MaxSum, i, j,k;
MaxSum = 0;
for (i = 0; i < N; i++)
{
for (j = i; j < N; j++)
{
ThisSum = 0;
for (k = i; k < N; k++)
{
ThisSum += A[k];
}

if (ThisSum > MaxSum)


MaxSum = ThisSum;

}
}
return MaxSum;
}
#endif

#ifdef QuadraticAlgorithm // N^2 Algorithm


int MaxSubsequenceSum(const int A[], int N)
{
int ThisSum, MaxSum, i, j;
MaxSum = 0;
for (i = 0; i < N; i++)
{
ThisSum = 0;
for (j = i; j < N; j++)
{
ThisSum += A[j];
}

if (ThisSum > MaxSum)


MaxSum = ThisSum;

}
return MaxSum;
}
#endif

#ifdef NlogNAlgorithm // NlogN Algorithm

static int Max3(int A, int B, int C)


{
return A > B ? A > C ? A : C : B > C ? B : C;
}

static int MaxSubSum(const int A[], int Left, int Right)


{
int MaxLeftSum, MaxRightSum;
int MaxLeftBorderSum, MaxRightBorderSum;
int LeftBorderSum, RightBorderSum;
int Center, i;

if (Left == Right) //Base Case


if (A[Left > 0])
return A[Left];
else
return 0;

Center = (Left + Right) / 2;


MaxLeftSum = MaxSubSum(A, Left, Center);
MaxRightSum = MaxSubSum(A, Center + 1, Right);

MaxLeftBorderSum = 0;
LeftBorderSum = 0;

for (i = Center; i >= Left; i--)


{
LeftBorderSum += A[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}

MaxRightBorderSum = 0;
RightBorderSum = 0;

for (i = Center + 1; i <= Right; i++)


{
RightBorderSum += A[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}

return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);


}
int MaxSubsequenceSum(const int A[], int N)
{
return MaxSubSum(A, 0, N - 1);
}

#endif

#ifdef LinearAlgorithm // N Algorithm

int MaxSubsequenceSum(const int A[], int N)


{
int ThisSum, MaxSum, j;
ThisSum = 0;
MaxSum = 0;

for (j = 0; j < N; j++)


{
ThisSum += A[j];

if (ThisSum > MaxSum)


MaxSum = ThisSum;
else if (ThisSum < 0)
ThisSum = 0;

return MaxSum;
}

#endif

Potrebbero piacerti anche