Friday, 12 August 2016

Well Organized Unit Tests

Some people write unit tests by copying all of the arrange code to every unit test, so they will end up with code like this:

[TestMethod]
public void MyFunction_with_some_condition_does_something()
{
    // Arrange
    // 20 lines of setup code
    ...

    // Act
    ...

    // Assert
    ...
}

[TestMethod]
public void MyFunction_with_some_other_condition_does_something_else()
{
    // Arrange
    // The same 20 lines of setup code as above with one minor modification
    ...

    // Act
    ...

    // Assert
    ...
}

Of course the problem with this is that if you change one thing in your method's implementation, you may need to change every unit test, and it can get messy.  This makes people lazy, and they will neither want to make changes, nor fix their unit tests.  I'm not sure why people forget about good programming principles like DRY when it comes to unit tests.  So you could do something like this, and keep your unit tests small (3 or 4 lines each), easy to read and change:

private MyFunctionRequest myFunctionRequest;

private void Arrange_MyFunction(bool condition1 = false, bool condition2 = false)
{
    myFunctionRequest = new MyFunctionRequest
    {
      ...
    };
    if(condition1)
    {
      ...
    }
}

[Test]
void MyFunction_with_some_condition_does_something_else()
{
    // Arrange
    Arrange_MyFunction(condition2:true);

    // Act
    target.MyFunction(myFunctionRequest)

    // Assert
    ...
}

This looks okay, until you start to work with multiple methods in a class and find that you have to split your test class into regions and you have member variables that only pertain to a specific region.  Using regions is often an indication that your class is doing more than it should.  A better way to organise your tests is to have one class for each method being tested, like this:

[TestClass]
public class MyServiceTests
{
    protected MyService target;

    [TestInitialize]
    public void Init()
    {
        target = new MyService();
    }

    [TestClass]

    public class MyFunction_Method: MyServiceTests
    {


        private MyFunctionRequest request;



        private void Arrange(bool condition1 = false, bool condition2 = false)
        {
            request = new MyFunctionRequest
            {
                //...
            };
            if (condition1)
            {
                //...
            }
        }

        [TestMethod]

        public void With_some_condition_does_something()
        {
            // Arrange
            Arrange(condition1:true);

            // Act
            var actual = target.MyFunction(...);

            // Assert
            ...
        }

        [TestMethod]

        public void With_some_other_condition_does_something_else()
        {
            // Arrange
            Arrange(condition2:true);

            // Act
            var actual = target.MyFunction(...);

            // Assert
            ...
        }
    }
}

If your method being tested is particularly complicated, you could break it down even further, like this:

[TestClass]
public class MyServiceTests
{
    protected MyService target;

    [TestInitialize]
    public void Init()
    {
        target = new MyService();
    }

    [TestClass]

    public class MyFunction_Method: MyServiceTests
    {
        private MyFunctionRequest request;

        [TestInitialize]
        public void Init_MyFunction_Method()
        {
            request = new MyFunctionRequest();
        }

        [TestClass]
        public class With_some_condition: MyFunction_Method
        {
            [TestMethod]
            public void Does_something()
            {
            }
        }
    }
}

In Visual Studio, your solution explorer will look like this:


Friday, 24 June 2016

C# In Memory Search Performance Comparison

Just in case one ever wants to do really fast in memory searches, it's useful to know which classes are the fastest, so I did some tests.  Here are the results from searching for a million integers in an array of a million integers.

Warming up...

Single threaded search...

Testing HashSet...
Create (and sort) took 209ms
Search took 208ms
Total time 417ms

Testing Dictionary...
Create (and sort) took 375ms
Search took 117ms
Total time 492ms

Testing BinarySearch...
Create (and sort) took 187ms
Search took 554ms
Total time 741ms

Testing SortedList...
Create (and sort) took 419ms
Search took 543ms
Total time 962ms

Testing HashTable...
Create (and sort) took 1180ms
Search took 530ms
Total time 1710ms

Multithreaded search...

Testing HashSet...
Create (and sort) took 114ms
Search took 65ms
Total time 179ms

Testing Dictionary...
Create (and sort) took 218ms
Search took 55ms
Total time 273ms

Testing BinarySearch...
Create (and sort) took 186ms
Search took 168ms
Total time 354ms

Testing SortedList...
Create (and sort) took 431ms
Search took 171ms
Total time 602ms

Testing HashTable...
Create (and sort) took 972ms
Search took 343ms
Total time 1315ms


And here's the source code I used to get these stats:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Collections;

namespace PerformanceTesting
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            var warmUp = Enumerable.Range(0, 1000000)
                .Select(i => rnd.Next())
                .Distinct()
                .Take(100000)
                .ToArray();
            var randomIntegersToStore = Enumerable
                .Range(0, 10000000)
                .Select(i => rnd.Next())
                .Distinct()
                .Take(1000000)
                .ToArray();
            if (randomIntegersToStore.Count() != 1000000)
                throw new NotSupportedException("Incorrect number of integers");
            var randomIntegersToSearchFor = Enumerable.Range(0, 1000000)
                .Select(i => rnd.Next())
                .ToArray();
            var tests = new List<ITest>
            {
                new HashSetTest(),
                new DictionaryTest(),
                new BinarySearchTest(),
                new SortedListTest(),
                new HashTableTest()
            };
            Console.WriteLine("Warming up...");
            Console.WriteLine();
            foreach(var test in tests)
            {
                test.Initialize(warmUp);
                test.Search(warmUp, false);
            }
            Console.WriteLine("Single threaded search...");
            Console.WriteLine();
            RunTests(tests, warmUp, randomIntegersToStore, randomIntegersToSearchFor, false);
            Console.WriteLine("Multithreaded search...");
            Console.WriteLine();
            RunTests(tests, warmUp, randomIntegersToStore, randomIntegersToSearchFor, true); Console.ReadLine();
        }

        private static void RunTests(IEnumerable<ITest> tests,
            int[] warmUp, int[] randomIntegersToStore, int[] randomIntegersToSearchFor,
            bool multithreadedSearch)
        {
            foreach (var test in tests)
            {
                test.Initialize(warmUp);
                Console.WriteLine("Testing " + test.GetType().Name.Replace("Test", "") + "...");
                var stopwatch = Stopwatch.StartNew();
                test.Initialize(randomIntegersToStore);
                stopwatch.Stop();
                var createTime = stopwatch.ElapsedMilliseconds;
                Console.WriteLine("Create (and sort) took " + createTime + "ms");
                test.Search(warmUp, multithreadedSearch);
                stopwatch.Restart();
                test.Search(randomIntegersToSearchFor, multithreadedSearch);
                stopwatch.Stop();
                var searchTime = stopwatch.ElapsedMilliseconds;
                Console.WriteLine("Search took " + searchTime + "ms");
                Console.WriteLine("Total time " + (createTime + searchTime).ToString() + "ms");
                Console.WriteLine();
            }
        }

        interface ITest
        {
            void Initialize(int[] randomIntegers);
            void Search(int[] randomIntegers, bool multiThreaded);
        }

        class HashSetTest : ITest
        {
            private HashSet<int> hashSet;
            public void Initialize(int[] randomIntegers)
            {
                hashSet = new HashSet<int>(randomIntegers);
            }

            public void Search(int[] randomIntegers, bool multiThreaded)
            {
                if (multiThreaded)
                    Parallel.ForEach(randomIntegers, i => hashSet.Contains(i));
                else
                    foreach (var i in randomIntegers)
                    {
                        hashSet.Contains(i);
                    }
            }
        }

        class BinarySearchTest : ITest
        {
            private List<int> list;
            public void Initialize(int[] randomIntegers)
            {
                list = new List<int>(randomIntegers);
                list.Sort();
            }

            public void Search(int[] randomIntegers, bool multiThreaded)
            {
                if (multiThreaded)
                    Parallel.ForEach(randomIntegers, i => list.BinarySearch(i));
                else
                    foreach (var i in randomIntegers)
                    {
                        list.BinarySearch(i);
                    }
            }
        }

        class SortedListTest : ITest
        {
            private SortedList<int, int> list;
            public void Initialize(int[] randomIntegers)
            {
                list = new SortedList<int, int>(randomIntegers.ToDictionary(i => i));
            }

            public void Search(int[] randomIntegers, bool multiThreaded)
            {
                if (multiThreaded)
                    Parallel.ForEach(randomIntegers, i => list.ContainsKey(i));
                else
                    foreach (var i in randomIntegers)
                    {
                        list.ContainsKey(i);
                    }
            }
        }

        class DictionaryTest : ITest
        {
            private Dictionary<int, int> dictionary;
            public void Initialize(int[] randomIntegers)
            {
                dictionary = randomIntegers.ToDictionary(i => i);
            }

            public void Search(int[] randomIntegers, bool multiThreaded)
            {
                if (multiThreaded)
                    Parallel.ForEach(randomIntegers, i => dictionary.ContainsKey(i));
                else
                    foreach (var i in randomIntegers)
                    {
                        dictionary.ContainsKey(i);
                    }
            }
        }

        class HashTableTest : ITest
        {
            private Hashtable hashTable;
            public void Initialize(int[] randomIntegers)
            {
                hashTable = new Hashtable(randomIntegers.ToDictionary(i => i));
            }

            public void Search(int[] randomIntegers, bool multiThreaded)
            {
                if (multiThreaded)
                    Parallel.ForEach(randomIntegers, i => hashTable.ContainsKey(i));
                else
                    foreach (var i in randomIntegers)
                    {
                        hashTable.ContainsKey(i);
                    }
            }
        }
    }
}

Wednesday, 14 January 2015

Resharper settings for C#

There used to be some useful Resharper settings at http://daniellang.net/5-resharper-settings-for-c4-coding/, but Daniel Lang, the guy who wrote them has since lost that page.  So, as I figure out my Resharper settings again, I'll post them here.

The idea is that if you don’t like this formatting:













...and prefer this:



















...In Code Editing - Other, at Align Multiline Constructs make sure that Array, object and collection initializer is unchecked.



And, according to Igal on Stack Overflow, the following should also be set, however they appear to be set by default:

  1. In Braces Layout, set Array and object initializer to At Next line (BSD Style).
  2. In Other, make sure that Continuous line indent multiplier is set to 1.

Saturday, 5 January 2013

How to Write Super Fast Code

The great thing about programming is that the proof is in the pudding.  If you've done a good job, your program works, meets the requirements and doesn't throw exceptions at the user.  The same goes for performance.

Writing uber fast code is a fun challenge that can be very rewarding.

Consider a conversation like this:

Code reviewer:  If you create a new variable and typecast it, and then check it for null, it will be faster than if you just use "is."

Developer:  Why do you say that?

Code reviewer:  Check out www.programming-guru.com/whatisayistruth.  In his article, Sir Jon Skeet MD PHP MCSD, says so.

Developer:  Here's some code which tests the performance of both versions.  My version is 0.00001 milliseconds faster.

The conversation is over, and there's no need for a pointless debate.

Performance is something that a programmer should keep in the back of his mind at all times, however in most cases the readability of code is the most important.  One only needs to ensure that something performs quickly if there's a chance that it will be noticeably slow.

Many years ago, when I was still in school, I wrote a program that needed to be amazingly fast.  I wanted to squeeze as many calculations per clock cycle that I possibly could.  Because of my need for speed, I chose to write it in assembler.  And so, it looked something like thousands of lines of this:

MOV AX, 42
JMP CX
DOG BRK
FOX 1
R2  D2
SUB MRN, DX
C3  PO
RAB BIT
etc., etc....

Okay, I've forgotten a lot of assembler, so the example may be inaccurate, but at least it worked.  Well, not exactly... because from time to time it would access invalid memory addresses and I'd have absolutely no idea why, and my computer would just freeze, or restart, or whatever computers used to do back in the DOS days.

So, how does one write super fast, stable, readable code?

Here are the steps:
  1. Find the problem areas.  There's no need to make any changes in code that is not slow.
  2. Measure the time taken.
  3. Write functionality tests.  If you're using a test driven approach, you should already have tests to ensure that any changes will not change the functionality.  If you don't, then write them.  
  4. Additionally, you could also write performance tests, like unit tests, which indicate a problem if an area of code is changed to be slower than it should be.
  5. Make your changes.
  6. Measure the performance.
1.  Finding the problem areas.

Areas that have the potentially to cause trouble are calls to slow hardware, like network calls and loading large files, calls to slow third party methods, and loops within loops.

If you've already written the code and you want to find out where the bottlenecks are, you can use a profiler.    I like ANTS Performance Profiler for .NET.  Start by fixing the biggest bottlenecks.

If you're writing the code and just want to make sure that it's efficient, then look out for the three potential problem areas that I mentioned earlier, calls to slow hardware, calls to slow third party methods and loops within loops.

On the subject of loops within loops, I want to make a quick comment about LINQ, .NET's slick way of working with lists.  The important thing to understand about LINQ is when it runs the code;  It only runs the code when you actually ask for the values:

For example, if you have something like this:

public IEnumerable Dogs
{
    get
    {
        return Animals.OfType();
    }
}

It would be very efficient to do something like this...

var dogs = Dogs;

...because the variable dogs will know how to return a list of dogs, but won't actually loop through the list of Animals until it's used.

However, this would be very inefficient...

for(int i = 0; i < Dogs; i++)
{
    Dogs.ElementAt(i).Bark(); // It will loop through the Animals list here
}

...because it will loop through the entire Animal list every time you call Dogs.ElementAt().

This is far better:

foreach(Dog dog in Dogs)
{
    dog.Bark();
}

The following, although not ideal, but useful if you want to work with i, will be almost as fast as the above code:

var dogs = Dogs.ToList(); // It will only loop through the Animals list here
for(int i = 0; i < dogs.Count; i++)
{
    dogs[i].Bark();
}

2.  Measure the time taken

You can time a specific piece of code in C# like this:

var watch = new Stopwatch();
 
watch.Start();
for (int i = 0; i < 1000000; i++) { }   // Execute the task to be timed
watch.Stop();

To cater for caching and JIT compilers, it's usually good to run your code once just before timing it.

3.  Write functionality tests

4.  Write performance tests

Just in case you want to ensure that neither yourself, nor anyone else changes anything to drastically increase the time taken then you could write a performance test.

In C#, the easiest way to test is probably using TimeoutAttribute, eg.

[Timeout(200)]

...but using a timer, like the Stopwatch class, will allow you to be more specific about exactly what you're testing and why you need it to be fast.  In fact, the Timeout attribute can be extremely unreliable, especially if the test runs before any of the other tests, so it's better to use a timer.

The acceptable time in this test should be a lot more than what it actually takes, because the speed of a test can change according to the computer it runs on and the other processes that are running simultaneously.

A more accurate way to do this would be to copy an exact duplicate of your high performance code into the test, and test that it isn't much slower.  It's not ideal, but I don't think there's a perfect way to do this.

For example:

public void MyTest()
{
    const int iterations = 10;
    const long buffer = 200 * iterations;
    var originalCodeTimer = new Stopwatch();
    var currentCodeTimer = new Stopwatch();
    for(var i = 0; i < iterations; i++)
    {
        originalCodeTimer.Start();
        MyOriginalCode();
        originalCodeTimer.Stop();

        currentCodeTimer.Start();
        target.Foo();
        currentCodeTimer.Stop();
    }
    if (currentCodeTimer.ElapsedMilliseconds > 
        originalCodeTimer.ElapsedMilliseconds + buffer)
    {
        Assert.Inconclusive();
    }
}

private void MyOriginalCode()
{
    // A complete copy of the code or a call to a copy of the code
    // that I originally wrote and timed
    // ...
}

In order to get more accurate timings it's usually best to run the method being tested a few times and get an average time.

Of course, since this isn't an exact measurement it should probably be treated differently to normal tests.  You may want to consider keeping these tests separate from others, so they are not run every time your unit tests and integration tests run.  Another way to do this might be to use Assert.Inconclusive() if you're using MSTest.  Instead of showing a red X or a green tick, this shows a yellow exclamation mark, and places the test result under Skipped Tests.  That's not exactly what it would mean, but it will attract attention and people can see quite easily why it was skipped if you make it clear in your test.

You could do something like this:

if(timeTaken > expectedDuration * 2) 
{
    if(timeTaken < expectedDuration * 4)
        Assert.Inconclusive("Took two to four times expected duration.");
    else
        Assert.Fail("Took four times expected duration.");
}

5.  Make your changes.

In most cases, what you'll be looking to do is this:

    Any slow code that can be called less often should be called less often.

You may be tempted to use multi-threading in an attempt to increase speed.  Multi-threading increases the complexity of your application and doesn't always make it faster.  Measure the performance and decide if the increased complexity is worth the performance gain.  If you decide to go with multi-threading, check that you've considered other alternatives, the target environment, and thread safety.

6.  Measure the performance.

And only keep your changes if your measurements confirm that it's faster and it passes your testing.


Images:

1. Courtesy of Jon Whiles at FreeDigitalPhotos.net

Wednesday, 2 January 2013

The Characteristics of a Master of Programming

Today I was thinking about the characteristics that a master of programming has.  From experience I have found that some personality traits can be learned.

This is the list of characteristics that I came up with:

  • He loves programming.
  • He enjoys being creative.
  • He is organized.
  • He is calm.
  • He has lots of knowledge and experience.
  • He enjoys learning.
  • He is open minded, so he likes asking questions and getting his work peer reviewed, and does the best he can with the information he receives.
  • He loves challenges and is confident in his ability to solve any problem.
  • He is 100% focused on creating perfect software.  Nothing else matters.
  • He is always looking for the most effective way to write a piece of code or solve a problem.
What do you think?

Saturday, 22 December 2012

What Should a Programmer Learn?

I've come across a few kinds of thinking when it comes to hiring developers:

It seems that most, especially agents, try to look for very specific skills.  I remember speaking frankly to a recruiter and telling them, "Well, you're going to have a very difficult job finding the person you're looking for."  And they agree'd...  They had been looking for a while, and hadn't found anyone yet, even though they were offering a very high salary.  They were looking for a .NET developer who had five years experience in building Metastorm BPM solutions.  The idea sounded a bit unrealistic to me.

On the other extreme, I once received a phone call from a company trying to get an ASP.NET developer.  At the time I hadn't had any experience in ASP.NET, but they didn't seem too worried and invited me to come for the interview regardless.  I also spoke to a friend of mine recently, who told me that their company has a policy that they don't hire people for specific skills, but rather look for good, smart, experienced programmers who they can train to do the job.

The third kind of thinking is a hiring within the specific industry or type of work.  This kind of thinking makes it very difficult for a good programmer to get into the favourite industries, like game development.

On the positive side, seeing as different companies hire for different reasons, it may be possible to get into one company where a similar company would reject you for not being in the right blood group, or having the wrong star sign, or something equally ridiculous.





So, let me start with what I think is the most important:

What to learn to become an amazing programmer, regardless of the specific skill or industry.

The basic skills required for a junior programmer usually include some object oriented programming language, the ability to create a relational database, and SQL.  If you can afford it, the best way to learn these is probably to go to university.

The next thing you'll probably want to learn is design patterns.  You can either look up the most common design patterns on the internet, or read a design pattern book, such as Design patterns : elements of reusable object-oriented software or Design Patterns For Dummies.  Code Complete is a famous book which teaches how to write quality code, but it's quite old, so there may be a more up to date book.  There are also books on patterns for specific areas of software development, so you could get a book specifically about design patterns in ASP.NET for example.

If you look at job descriptions, you may find three letters which pop up in almost every advert: "TDD."  Once you have a good knowledge of the basics of programming, you need to learn Test Driven Development.  It may seem strange, but I would go as far as to say that if I ran a company, I would expect all of my developers to either have read a book on TDD before they're hired, or I would insist that they read one as soon as they start.  If you're a C# developer, I would recommend Wrox's Professional Test Driven Development with C#.

Test driven development is not as simple as writing tests before doing the development, but is rather a comprehensive method of developing extremely high quality code, including design patterns, best practices, dependency injection, refactoring, unit testing, integration testing and mocking; knowledge and understanding that every programmer should have.

There is some debate about TDD, although for me it's like this:  If you're developing something extremely simple for your own use, you don't need to worry about TDD.  If you're developing a complex banking application that processes billions of pounds, you absolutely must use TDD.  Everything in between requires the programmer's knowledge and experience with TDD in order to make the right decision.

You should know about DDD (Domain Driven Design), and ensure you understand principles like SOLID, YAGNI and DRY.  Depending on the type of development you're going to be doing, you may also wish to look into document databases (e.g. MongoDB).  Modern distributed applications might use micro services, message queues (like RabbitMQ) and cloud computing (like Azure or AWS) so check those out.  If you're doing web development you should understand the MVC pattern, and for WPF development you should understand MVVM.

Learning a new programming language or skill.

Consider the following two approaches to learning a programming language:  The first is to read the entire manual and the other is to learn the basics and then look up how to do things as you go along.

I have tried both of these approaches and, well, the best approach is probably somewhere in the middle.

The problem with trying to learn an entire programming language is that programming text books are typically around a thousand pages.  It takes a lot of work to digest all of that information.

On the other hand, trying to learn a programming language on the fly may cause you to miss out on some fantastic features of the language that you've never heard of before.

The following is my method of choice:

I accept that learning a new language is a big task and set myself a reasonable goal for how long I'm going to take to learn it.  Then I find a book which teaches by having me build a project as I learn.  Learning programming requires lots of practice, so you can't just read it and expect to remember everything.  If one is lucky enough to be working with the same language that one is learning, then it is perfect for remembering information.  If not, one should probably work on one's own project which requires the skills being learned.  I also like to spend some time on stackoverflow.com, a very useful resource for programmers, but instead of asking questions, I try to answer questions on the topic that I'm learning.

Learn about the industry you want to work in.

While I don't consider this as important as the previous two topics, it can be very important in certain circumstances.  For example, if one wants to work as a games developer one will need to do some research to find out what skills are required for the jobs that are available, and then make a decision as to whether or not it's worth the effort to make yourself marketable enough.

If you don't really care about the industry, then do start researching as soon as you get an interview or find out which industry you may be working in.  It will help you a lot in your job if you know a lot about the company you work for and the software which they develop.

Ongoing learning.

Programmers have to constantly keep up to date with the latest in software development.  I'd recommend subscribing to news about your area of interest, and setting aside some time every week or two to find out what's new.

And finally, ...

... please learn how to type :)

If you're going to spend your entire life typing every day, you really need to do it properly.  Get a cheap program which teaches you to type, and if you like you can get a game like Typing of the Dead.  Typing of the Dead is an addictive game where you have to type quickly in order to kill the zombies.  It's good fun!


Images:

1. Courtesy of jscreationzs at FreeDigitalPhotos.net
2. Courtesy of adamr at FreeDigitalPhotos.net
3. Courtesy of David Castillo Dominici at FreeDigitalPhotos.net

Thursday, 22 November 2012

How to Focus on Programming

In order to become a master of programming one needs knowledge and the ability to focus while putting that knowledge into practice.  I will begin this blog by teaching you how to focus, and then move onto knowledge.

Focusing your entire consciousness on what you're doing is essential for any job that requires intelligence.  Not only does focusing give you the ability to be more productive, but it also helps you enjoy your job and reduces stress.

In order to learn how to improve my concentration,  I looked for books on the subject.  It seems that most books on concentration come from Eastern religions and are more about meditating than learning to focus at work.  I was looking for something a bit more scientific.  I read a book called, "Can I Have Your Attention?: How to Think Fast, Find Your Focus, and Sharpen Your Concentration."  Unfortunately the book seemed to be more for martial artists, and other people who need to think quickly, rather than those who need to solve complex problems.

Having read a number of books on thinking and the mind, and having fourteen years of experience as a professional programmer, I think that I can share some good advice.  Hopefully reading this will be more efficient than trying to find a good book on concentration and reading it.


Your sub-conscious makes you think about things by noticing related things in your field of vision.

Pause for a moment, and think about that heading.

Imagine you're in a pitch black room, and cannot see anything at all, except for your keyboard, mouse and computer screen.  Your computer has no wallpaper and no icons.  The only thing you see is your IDE.  This is the ideal environment for focusing on programming.  Your mind has absolutely nothing visual to focus on, except for your work.

Of course it's not always practical.  If I minimize my browser, this is what my desktop looks like right now:


My wallpaper is a pretty picture of the head office of the company I work for.  No, I don't have to have this wallpaper.  I simply put it there to generate a good feeling about the company, encouraging my sub-conscious mind to enjoy and focus on work.

I have loads of programs, but I don't need to see icons for every one of them.  I have only five icons on my desktop, but I never use any of them.  One of the icons is for a tool that I wrote specifically to do my most common work tasks.  I don't use the icon, because I've created a keyboard short-cut for it, which is quicker and easier.

Here are some ways to remove visual distractions, both conscious and subconscious:

- Clean your desk, removing everything that doesn't need to be there.
- Clean your desktop, moving all your icons into a folder, so that your desktop is empty.
- Use a wallpaper that encourages you to do well, or at least doesn't encourage you to think about anything else.

Remove audio distractions

Some people like to write code while listening to music.  If that works for you, then great.  My work environment is quiet enough, I can get into the zone without any problems, but at home I close the door and wear ear plugs.  Technically they're attenuators, also known as musicians earplugs.  I had them custom made to fit my ears, and they cut out most of the noise around me.  Not all though, as they're really meant to limit loud noises, rather than eliminate all audio.

Remove internal dialogue distractions

I find the most difficult time to concentrate is after I've had a controversial discussion.  My mind seems to get excited and not want to think about anything else.  This is why the best time to program is after sleeping, when your mind is empty.  Here are some suggestions:

- Never do anything too interesting before work or during your lunch break.
- Don't check your Facebook / personal email during work time.

I suppose I could summarize the above by saying that up until you leave work you should have a very dull existence... this will allow you to enjoy your programming more, while not thinking about anything that could be more interesting.

Remove excitement and anticipation distractions

One's mind seems to work in a relative sort of way, meaning that the more excitement you have in your life, the less exciting programming will be, and the less excitement you have in your life, the more exciting programming will be.

If you have to do something which is mentally exciting then you need to separate it from programming.  Do it somewhere completely unrelated to work, and at specific times which are not near to programming time, and especially not before programming.

- Don't use your work computer or environment for anything which is too exciting.  Your mind will relate your computer / environment to that activity, and try to get you to do that instead.
- If there's something your mind keeps thinking about instead of what you want to focus on, learn how to make decisions and decide not to think about that at all, or try and understand why you're thinking about it, and remove the cause.

Remove physical distractions

- Get enough regular sleep (seven and a half to eight hours).
- If you're tired, lie down for ten to twenty minutes.  It doesn't matter if you fall asleep or not - the break will help.
- Eat if you're hungry, but...
- Don't eat a big lunch unless you're planning to have a nap afterwards.  Work out how much you can eat without feeling tired.

Remove interruptions

A tiny interruption could send your mind down a different path, costing you minutes of development time.

- Switch off any real time messengers, like Skype.
- Close Outlook
- Unsubscribe to any emails you don't need.
- If you have a fancy email client, use it to write rules to automatically recycle emails which aren't important.
- Switch off your phone

(Basically switch off anything that could interrupt you.)

Set specific times of the day to read your work email, for example, every three hours.  Read all your emails, respond to all of them, and then close your email client.

Be healthy

I've always been pretty healthy, so I don't have much experience with this, but these are the things that experts always say, so here I'm just writing down whatever sounds right :)

- Get regular exercise (something like jogging)
- Eat less sugar (reducing the amount of sugar you eat actually makes things taste sweeter)
- Eat a high fibre breakfast
- Don't smoke, take drugs, or do anything that is addictive and could distract you from your work
- Don't drink coffee - rather get enough sleep
- Don't drink too much alchohol

Focus@will

There's a website at https://www.focusatwill.com (and no, they didn't pay me to mention them).  They have some music that you can listen to which is supposed to help you focus.  You specify the amount of time to play for, which is a neat way of specifying how long you intend to focus for.  I like using the ambient music on their site to focus.  In other words it does actually work for me.  Whether or not it will work for you, I don't know... no harm in trying.

As always, any thoughts?  Agree?  Disagree?  Questions?  Let me know :)


Images:

1. Courtesy of Maggie Smith at FreeDigitalPhotos.net
2. Courtesy of imagerymajestic at FreeDigitalPhotos.net


Getting A Senior Backend Software Engineer Job in the AI Era

Disclaimer: None of this is professional advice. I'm not a professional advice provider man. For professional advice, chat to your local...