24 Practical Performance Tips for Programmers

Do you want to be better programmer? Do you want to get a higher programmer salary? Then you're in the right place.

These tips and techniques can be applied in many areas in life. Some of them may show shorter results while other may require more time. All depends on you and your will power for change.

All of these techniques are proven strategies based on my experience with programming for more than 15 years now.

Let's start!

1. Rewrite your old programs

Update and rewrite your old programs and scripts(This simple tip show my progress and evolution as a programmer). If you write a program you can give your 100% and your best knowledge at the moment.

For example lets see my old version of a program for finding prime numbers:

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2,n):
        if n % i == 0:
            return False
    return True

This program is fine and return the correct result in a reasonable time for a single number. But later I wanted to solve a problem on Project Euler and I just copy paste this version and I found that my program was terrifically slow. After some time of investigation I found the reason for this code to be in this code snippet. Maybe you will find really easy what is the cause of this issue.

So after some time of analyzing I've changed:

for i in range(2,n/2):

This help a bit but after additional web research on the web and some math books I ended with this is the improved version of the program:

import math

# check if a number is prime, check up to square of n
def is_prime(n):
    if n <= 1:
        return False
    sqrt = math.floor(math.sqrt(n))
    for i in range(2, 1 + sqrt):
        if n % i == 0:
            return False
    return True

As you can see the changed is:

sqrt = math.floor(math.sqrt(n))
for i in range(2, 1 + sqrt):

several points to mention:

  • difference in time was several minutes which make the difference for this Euler problem: 10001st prime
  • The method floor() returns floor of x - the largest integer not greater than x.
  • The method sqrt() returns the square root of x for x > 0.
  • If a number n is not a prime, it can be factored into two factors a and b:
    n = a*b
    If both a and b were greater than the square root of n, a*b would be greater than n. So at least one of those factors must be less or equal to the square root of n, and to check if n is prime, we only need to test for factors less than or equal to the square root.

From this story I've learned that it's a good idea of reviewing and rewriting the old programs. We can find better ways or fixing bugs. You can also verify for bad comments or code style from your old programs.

2. Translate programs from one programming language to another

It's no secret that the more languages you know the more attractive you will be in the eyes of HR-s. Even other programmers may think of you as a genius and master. But it's less obvious that translating from one language to another will improve your thinking. Another benefit from translation from one programming language to another is thinking out of box. Sometimes due to missing features and functions you will need to work out new solution of existing problem.

For example I wanted to solve another problem related to math and numbers. For this reason I had to split a number into list of its digits:

93453 -> [9, 3, 4, 5, 3]

In python this can be done very easily with a single row like:

[int(d) for d in str(n)]

Later I wanted to move on Java. I was not able to translate this line of code literally so I ended up with a solution which I remember from my student years:

while (number > 0) {
    print( number % 10);
    number = number / 10;
}

Both solutions has their strong and weak points. Most probably after Java 8 the translation would differ a bit.

My key points from this advice are:

  • translation of programming languages is a good way to learn new language
  • programming language is less important than solution and the algorithm. In most cases the good solution and 'bad' language will beat bad solution and good/popular language

3. Learn new programming languages

Many people prefer to master a single language and to stay with this one for their whole career. For me this is bad. There's nothing wrong in mastering a language. The problem is the lack of knowledge for the rest of the world.

It's really important to have at least basic knowledge in several other supportive languages. This will enrich your skill set and allow you to pass the limit of your favorite language ( I consider that all languages have some weak points ).

For example if you want to count the number of words in a column of a table you can find many different approaches to this problem. But knowing SQL can help you with finding the fastest and easiest possible solution like:

SELECT description, 
LENGTH(description) - LENGTH(REPLACE(description, ' ', '')) + 1
FROM test.city

More information on this problem here: MySQL count words or phrases in a column.

Solving this problem in Java or Python can take too much time or even to be endless if the data set is too large.

On the other hand is not necessary to go in the other direction with learning to much languages. Keep to the old but gold formula:

Do not collect languages or skills beyond what is useful

4. Read books for programming and algorithms

Some programmers may wonder why reading is important if they are senior or experienced. Exists so many other interesting things to do with one's time.

Then why is reading of programming literature important?

Reading is a vital skill in solving problems and dealing with technical requirements. Having good reading skills will boost your performance and it will decrease the number of errors in your daily work. On the other hand there solution and algorithms which must be read and understand by good detailed explanation. Do you expect that life time work of someone can be reproduced in hours. Poor reading skills increases significantly the amount of time it takes to understand and communicate a problem.

Reading is also important because it develops the mind. Programming is all about strong logic and mind set. The mind is not a muscle but it needs exercise and trainings. Reviewing and understanding the other people code is one way the mind grows.

Reading develops the creative side of people and opens new ways. You will look inside new world of ideas and solutions. Creativity is really important for programmers and people in IT world.

For example famous problem of Carl Friedrich Gauss - who, as an elementary student, amazed his teacher with how quickly he found the sum of the integers from 1 to 100 to be 5050. Gauss simply found a pattern of: (1 + 100), (2 + 99), (3 + 98) .. So finally end with : 50 pairs × 101 (the sum of each pair) = 5,050.

The best way to find this kind of solutions and ideas by reading them in the books. Let's be honest - people who can 'invent' this solution are real giants in their knowledge area. Rather than trying to solve already solved problems try to find some new ones and reuse what is already found.

5. Create your own principle guide

Creating an code, style, naming and solution guide is really important. This guide will be your friend in the long journey of your career. Can you imagine to go in a new city in a foreign country without a map and dictionary. You will spend huge amount of time even for the simplest tasks.

The same can be applied for programming. Naming conventions will prevent you of creating all possible variations of a variable names like:

  • name
  • first_name
  • firstName
  • nameFirst
  • frstNm

On the other hand people who read your programs will have less confusion.

Code guide of your best solutions will save you time next time when you need to solve the same problem. No matter how simple is a given problem - solving it twice from 0 is better to be avoided ( except in some cases). Instead of losing time and mind power of solved problems - right them down in a file and later on - just reuse them.

Take this piece of code:

def fibBottom(i):
    fib = {}
    for k in range(i+1):
        if k <= 2: f = 1
        else:
            f = fib[k - 1] + fib[k - 2]
            print('calc', k , fib)
        fib[k] = f
    return fib[i]
print(fibBottom(6))

This is a simple Fibonacci functions which include technique from dynamic programming named: bottom-up. Of course I can write it every time I need Fibonacci or Bottom-Up but I prefer to copy paste it directly and if needed to change it.

More on Python Fibonacci sequence optimized 4 examples: Python Fibonacci sequence optimized 4 examples.

So next time when I want to get Fibonacci I'll visit this address and use it.

6. Avoid distractions or do focus work

Programming is pure mental process which requires focus and less distractions. Unfortunately it's very difficult in the modern world to decrease the number of interruptions in the office. Since it's so difficult to avoid them then it's better to control them better. Here I'll put my practical tips to fight with office distractions for programmers:

  • Read mails only two times per day - Actually when I go to my office I have several programs at computer startup and the mail client is not one of them. The mail client is set up to start at 10 in the morning and 16 in the afternoon. Before every new mail was distracting my attention and it was causing stop of my current task. Maybe it's important for managers and other roles to read their mails immediately. But as a experienced programmer I prefer to read it two times a day.

  • Use headphones for sound distractions. Work with quality headphones in open office places. The noise in the open office can be rather annoying. I have options to work in several different type of places - pure open office, small room for 4 people and my home. I'm most productive at my home since distractions are close to 0. My biggest problem is how to concentrate in the open space. In order to survive in such place - I need:

    • headphones
    • good music - actually it depends on the work and my mood. From house, instrumentals, rock and relaxing/chill out mixes
    • choosing a place with good light and less passing people
  • Small sign - Do not disturb or only in case of emergency. Put this sign on your desk on a visible place and be sure that people understand that this is really important for you. It can be difficult to explain to the designer why your solution needs concentration and it can be different from picking up a color.

  • Put your status to away or do not disturb in messengers like Skype and others. Teach people that you prefer to be contact it in this ways:

    • in first place by mails
    • if the problem needs discussion you can use messenger like Skype
    • Live meeting in the coffee room - scheduled one
    • Voice call
    • Unscheduled meeting - only if the topic is about salary increase :)

7. Spend 15 minutes to organize your daily task

Free 5 minutes in the beginning and 10 - 15 minutes at the end of each working day for:

  • Prepare ToDo list for next day
  • Organize and sort important files and scripts
  • Clean unnecessary stuff
  • List with uncompleted task for the next day
  • Prioritizing
  • Reaserch for new solutions

The next day start with what is left from the previous one. Do not start with facebook, news and other time wasting stuff. Use your list and jump on the easiest problems.

Be persistent and don't skip this part of your working day. This could be a good habit which is going to pay in future.

This is what I'm doing:

  1. Create a simple Notepad++ file named Todo
  2. At the end of the day I put remaining tasks and next ones
  3. Save all important code snippets and scripts in a special folder
  4. Clean temporary files
  5. Move all important documents in folders
  6. The next day open Todo.txt and start by the list

8. Use temporary Notepad++ clipboard file

During my work I have plenty of code, scripts and other useful snippets. In order to have control and way to filter important from meaningless information I use a simple Notepad++ file.

In this file the information is organized in sections like:

-- SQL

-- select last person
select max(id) from person;

-- count open orders
select count(*) from orders where status = 0;

-- Python

# simple lambda
mylist = [1,2,3]
print(list(map(lambda x: x ** 2, mylist)))

# lambda fibonacci
fib = lambda x : 1 if x <= 2 else fib(x-1) + fib(x-2)
print(fib(15))

# tuple vs list
list_num = [1,2,3,4]
tup_num = (1,2,3,4)

The good point about Notepad++ is that it keeps backup version of the files and in case of unexpected shutdown or blue screen you can easily restore your information from the back up folder. This is explained in the Notepad tutorial.

9. Focus on better solution, better code, better idea.

Instead of making it work or just workaround it. Try to be consistent in this process of constant searching for better ideas. This will help you to leave your comfort zone in programming and motivates you to try new stuff.

I remember back in the old time when I had to switch from C to Java. This was a huge step for me. Jumping in the dark and unknown. After several weeks I was more than happy to find that some problems can be easily solved in Java. The same was for the move from Java to Python.

When we master a language or a tool it's pretty normal that we want to use it rather to learn something new. Learning something new cost time and power will. But staying too long with something can cause troubles in long term.

This is what I'm doing:

  • In the beginning I tend to make a research for the best tool
  • I start with the one which is the most recommended and the one closest to my area of interests - machine learning -> python
  • after several weeks or months of work I'm doing a new research for something better
  • On a year basis I'm searching for last year best products or the new ones
  • Marking some problems based on my instinct which can be improved - later on I'm working on them in order to find different way to solve them.

For example working with groovy I was able to use code for permutation generation:

def perm(tokens) {
	if (!tokens || tokens.size() == 1) {
		return [tokens];
	}

	if (tokens.size() == 2) {
		return [tokens, tokens.reverse()];
	}

	def permutations = []
	for (def token : tokens) {
		def tail = tokens.collect() - token;
		def tail_perms = perm(tail)
		for (def p : tail_perms) {
			p.add(0, token)
			permutations += [p]
		}
	}
	return permutations
}

later I found that from version 1.7 Groovy offers new methods for permutations:

list.eachPermutation() 

which is much faster than the original code.

10. Periodically solve problems and test your skills

Sites like projecteuler.net and hackerrank.com offers interesting problems which can warm up your programming skills. You can test your level on these sites or use it as facebook replacement :) Replacing facebook with project Euler for one month boost by confidence and gave me many interesting solutions of known problems. I was able also to compare different languages and ways of thinking.

The other good point is of solving problems on such sites is testing your skills and progress in programming. Many companies use this sites or the problems published on them as part of their technical interviews. The more problems you meet the better you will be prepared. Some of the problems may required hours or days to be solved but if you know the solution you will be in a good position to work it out.

A friend of mine was invited on a interview this year 2018 and he was given 3 problems for 2 hours from hackerank. He wasn't not prepared for them and spent most of his time just to understand the problem. Finally he ended with 1 problem solved and another one started. Later on after persistent work persistently for a month on this site and he was able to complete this kind of problems in less than 2 hours.

Here it's important to mention that you need to understand and analyze the problem. Solving the problems is not enough if you want to be a good or best programmer. This is what I mean:

Problem 10 of Euler projects says:

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

You can solve it in python with sample code like this:

def fib(i):
    if i <= 2:
        return 1;
    else:
        f = fib(i-1) + fib(i-2)
        print('calc', i)
    return f

which is working but it would take long and it's not optimized. I knew that I can use some techniques from dynamic programming like bottom up or memoization. But reading the tread of the problem and the document with the analyze I found another good non recursion solution like for Fibonacci using OOP:

class Fibon:
    old = 1
    fib = 1
    current = 1

    def next(self):
        print('calc', self.current , self.fib)
        newFib = self.fib + self.old;
        self.old = self.fib;
        self.fib = newFib;
        self.current+=1
        return fib;

fibon = Fibon()
while(fibon.current < 5):
    k = fibon.next()
print(fibon.fib)

11. Find time for code quality self-control

Read your code before publishing or shipping to find confusing names, possible side effects or bad practices. Writing a code is a complex process which consist from several stages:

  • analyzing problem
  • writing a basic algorithm or outline steps of the solution
  • test your logic with example
  • implement your code
  • validate the code with the example
  • quality control time

Many people forced by the lack of time or driven by laziness skip some of the important stages of coding. From my experience I understood that skipping steps like code quality control can cause:

  • spending time in fixing defects rather than learning new things
  • code changes and reviews will take much more time even for the person who wrote the code
  • the number of defects in your code will decrease with the time
  • finally you will understand the difference between bad and good written code only by first glance.

Let me give you an example:

l = [2]
def p(x):
  for i in l:
    if i > x/2: return True
    if x % i == 0: return False
  return True

Maybe some of you guessed that this is testing prime numbers. This is the same code with some changes:

primes = [2]

# search for primes by testing up to square root
def is_prime(x):
  for i in primes:
    if i > sqrt(x): return True
    if x % i == 0: return False
  return True

12. Forget for temporary solutions

Programmers tent to be optimistic creatures promising impossible things for impossible time constraints. Later forced by the tight deadlines they produce temporary solution - combination from many sources and ideas. This can save the situation for short term and create a catastrophe in long term.

Have you ever manage system written in spaghetti style from many people, languages and ideas. This is one of the worst programmer's nightmares. The value of X is hardcoded on 5 places and related to 10 others. And the easiest way for you to solve it is to add another temporary solution - one more if and hardcode.

From my experience it's better to reject this problem or issue and explain to the responsible party that this problem needs more time and attention. Of course from manager point of view - the less time and resources the better which leads to many useless products on the market.

My advice here is to reject problems which can be considered as temporary solutions or to request for more time. Try to deep and find the real origin or the problem and not to add another level of confusion for the next people working on the system.

For example the problem below was easy to written with brute force and awfully slow:

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:

Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.

Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

My algorithm is generating big decimal numbers with precision 5000 and then walking on the decimal part to search for recurring cycles. Later I found this code on the tread of the problem which is much more efficient:

import itertools


def recurrent_length(n):
    # digits for unit fraction 1/n
    r = 10  # initial remainder (10/n)/10
    seen = {}  # remainder -> first pos
    for i in itertools.count(0):
        if r == 0:
            return 0  # divides evenly.
        elif r in seen:
            return i-seen[r]  # current position - first position
        seen[r] = i
        r = 10*(r % n)


lena, i = max((recurrent_length(i), i) for i in range(2, 1000))
print(i)

My algorithm was working and giving the correct answers in hours. It was a good temporary solution but rather ugly and ineffective. After a small research on the topic I was able to find much better solutions.

Conclusion

This is part one of 24 Practical Performance Tips for Programmers. No matter how good you are or how fast there is always a place for improvement. Learning and sharing experience with others is one the most valuable skills for humans. So please do share comments or add your ways to increase your performance and quality in the comment section below.

Related Article