# Efficient Algorithm Writing – Tricks and Examples

Efficient algorithm writing concerns the effectiveness of the overall system. Every real-life algorithm iterates at least once. Iteration may be explicit (due to the looping construct) or it may be implicit (due to recursion). Loops are the major contributor to the efficiency analysis of the algorithm. Sometimes the code within the loop executes thousands of times or even billions of times. A small gain in proper algorithm design greatly reduces the running time.

## Effectively using loops

It is just as important to write efficient algorithms as it is to have high-level hardware. The carelessly written algorithm often runs one time more or less than intended. The following three points should be considered while writing a looping construct:

**Initialization**

Choose the loop counter such that it can address the smallest possible instance of the problem. Consider the problem of summing the first n integers. The smallest possible instance is to add a zero number. In that case, the minimum value of the sum variable and the loop counter i will be zero.

```
i = 0
s = 0
```

**Find iterative construct**

Find the problem with the next smallest instance. A careful inspection of the loop and logic tells us that in each iteration variable i needs to be incremented and A[i] should be added to the partially computed sum.

```
i = i + 1
sum = sum + A[i]
```

The complete code segment would be :

```
i ← 0
sum ← 0
```**while** i < n **do**
i ← i + 1
sum ← sum + a[i] // Assume that array index starts from 1.
**end**

**Termination**

A number of iterations may be known in advance or it may depend on certain conditions to be satisfied. To find

5! loop should be iterated 5 times

The loop count is known in advance:

```
for (i = 1; i <= 5; i++)
{
. . .
}
```

The loop count is not predefined:

Sometimes loop may be forced to terminate from in-between

```
for (i = 0; i < n; i++)
{
if A[i] == x
break;
}
```

## How to write an efficient algorithm?

**Remove redundant operations:**

The computational cost of an algorithm is defined by its efficiency. People used to frequently write unneeded code within the loop. Redundant code that is repeated within loops has a negative impact on execution time.

The algorithm’s efficiency can be increased by carefully designing it. Consider the code segment below for determining pixel coordinates along the ellipse boundary:

**Algorithm **DRAW_ELLIPSE(a, b)
**for **x ← 0 to a **do**
y ← (b/a)*sqrt(a*a – x*x)
PlotPixel(x, round(y))
**end**

By relocating the constant computation outside the loop, a substantially better version of the above algorithm can be developed. The optimized ellipse algorithm is illustrated below.

**Algorithm **EFFICIENT_DRAW_ELLIPSE(a, b)
t ← b/a;
m ← a * a;
**for **x ← 0 to a **do**
y ← t*sqrt(m – x*x)
PlotPixel(x, round(y))
**end**

Constant division b/a and constant multiplication a*a are moved outside of the loop, and hence we reduce n multiplications and n divisions.

**Referencing Array**

One memory access corresponds to a reference to one array element. If the array is large, this may result in a significant number of memory accesses, slowing down the process. The algorithm’s efficient design can save a large amount of memory access.

Arrays are typically used to retain a huge amount of data and are accessible via the loop. Consider the following two scenarios for locating the array’s smallest element.

**Algorithm** POOR_FIND_MIN
k ← 0
**for** i ← 1 to n **do**
**if** A[i] < A[k] **then**
k ← i
** end
end
**Min ← A[k]

An efficient version of this algorithm would be:

**Algorithm **EFFICIENT_FIND_MIN
Min ← A[0]
**for **i ← 1 to n **do**
**if** A[i] < Min **then**
Min ← A[i]
k ← i
** end
end
**Min ← A[k]

The POOR_FIND_MIN algorithm requires two array accesses for each comparison, whereas EFFICIENT_FIND_MIN needs only one. Arithmetic on the array needs to address the calculation on each array access.

EFFICIENT_FIND_MIN compares A[i] with constant Min, which reduces the array access by a factor of two

**Late termination**

Sometimes, inefficiency in the program is also introduced due to unnecessary tests. The program keeps iterating after producing useful results. Consider the problem of linear search.

**Algorithm **POOR_LINEAR_SEARCH(A, Key)
Index ← -1
**for **i ← 1 to n **do**
**if **A[i] == key **then**
Index ← i;
**end**
**end
**
**if **Index == -1 **then**
print “Key not found”
**else**
print “Key found on index i”
**end**

An efficient version of this algorithm would be:

**Algorithm **EFFICIENT_LINEAR_SEARCH(A, Key)
flag ← 0
**for **i ← 1 to n **do**
**if **A[i] == key **then**
flag ← 1
**break**
**end**
**end**
**if **flag == 0 **then**
**print** “Key not found”
**else**
**print **“Key found on index i”
**end**

POOR_LINEAR_SEARCH goes on to iterate n times Key is found at the first location. whereas EFFICIENT_LINEAR_SEARCH breaks the loop once the Key is found, which makes it more efficient.

**Additional Resource**: Problems, Solutions and Tools. Click to read.

## Short Questions:

### Q: Suggest a few things to improve the efficiency of the code

We shall consider the following things while we write a code, to make it effective and faster:

- Remove redundant operations
- Referencing Array
- Late termination