Saturday, July 15, 2006

Getting to Deadline - Programmer Productivity Tips At Work (Getting to Done)

Getting to Deadline - Programmer Productivity Tips At
Work (Getting to Done)

Posted in Programming, Best Practices, Verification,
!Original Commentary, Career Skills, Workplaces at by
engtech

I am my own worst enemy when it comes to achieving my
deadline goals. These are tips / reminders I?ve found
useful through work experience.

Most of the tips are general, but some are
specifically suited to programmers/engineers in
situations with long compile/simulation phases
(compiling is the act of building an executable,
simulation is the act of running it to completion).
General Office Productivity Tips:Procrastination.It
comes down to inertia and momentum.

* Understand the problem. It is very easy to avoid
work you do not understand well enough to solve.
* Break it down. Break the larger problem into
smaller problems that conceptually you understand and
can tackle.
* Review milestones. They are closer than you
might think, and it can be a good kick in the pants to
think ?I have to get this feature done by Thursday?
instead of ?I have to get this all done in three
months?.
* Prioritization. Do not starve a high priority
feature for lack of understanding to feed a low
priority feature you know like the back of your hand.
* Just do it. Attack the problem, no matter how
feeble the attempt. Even if you throw out the work, it
increases your understanding. It is better try fail
than to waste time on something unrelated. Like
writing a blog post or checking the InterWeb. LIKE YOU
ARE DOING RIGHT NOW.
* Go for a walk. Can?t focus? Get away from your
desk and stimulate the blood flow to your brain. A
change of scenery can unplug a mental block.

Interruptions.

What is of concern isn?t the time lost servicing the
interrupt, it is the time spent context switching back
to the original problem. Interrupting someone in flow
can take 15 minutes for them to get back to the point
they were at before the interruption occurred.

* Net connectivity. Close email, web browser and
any messenger programs.
* Answering machine. Forward phone to voice mail.
* Office hours. If you are in a partial support
role, set up ?office hours? during the day where you
will answer questions.
* Meetings. Reduce the number of weekly meetings
wherever possible.
* Maximize use of time. Know what time of day you
are most effective and schedule the
interruptions/meetings to the time when you are not.

Environment.

The key is to create a work environment that is free
of distractions so that when you?ve achieved flow you
can maintain your focus on the problem at hand.

* Noise. Noise cancellation headsets or headphones
with music can cut down on the distracting nature of
open concept cube farm hell. Be kind to your
co-workers and never use a portable radio or your
computer speakers unless you are working late alone.
If you?re going to have an extended discussion with
someone move to a break room or an empty conference
room.
* Temperature. Have a portable fan to cool down
and a portable heater/sweaters to warm up if your cube
doesn?t have ideal temperature conditions.
* Snacks. Have food around so that hunger can be
satisfied without leaving the building. Don?t let your
belly be a source of distraction. Nothing that will
rot should be left out of sight. Some good low-fat
choices: apples, cans of tuna, microwave popcorn,
turkey sandwiches (if you have access to a fridge).
* Hydration. Have a bottle/cup of water on your
desk that you can sip from throughout the day. The
short term gains made from drinking coffee isn?t worth
the long term loses on memory, dehydration, and the
productivity lose from caffeine crashes.
Non-caffeinated herbal teas such as peppermint can be
useful for weaning yourself from coffee.
* Clutter. I am not hypocritically recommending
clean desks, but file away any papers that aren?t
germane to the problem at hand. When it comes time to
search the mountain of looseleaf, at least you will be
looking at stuff related to what you are working on.

Manage Expectations.

The biggest secret to getting more work done is having
less work to do.

* Give feedback. Do not tell management what they
want to hear, tell them what you think will happen.
* Accurate Estimations. Develop your estimation
skills so that when you say ?task X will take Y to do?
they believe you.
* Under commit and over deliver. Realistic
schedules give room to do a better job instead of
fighting to keep your head above water.

Avoid Burnout.

This is the most important tip. Meet the deadline in a
sane manner. Ever waste half an hour because you were
looking at the wrong results? Ever make a minor two
character typo that drastically changed results and
was very insidious to find because it ?looked right'??
If you were more alert that would not have happened.

* Relax. Find the balance between enough stress to
motivate but not so much stress that you lose the
ability to see the simplest solutions and recognize
time sinks before you fall into them.
* Minimum overtime. An hour of overtime is less
than a regular hour of work because you?re reducing
your overall ability to produce when you don?t get
proper rest. Find a balance between working hard and
working smart.
* Sleep. Don?t let thinking about work impact your
sleeping. Sleep debt has to be paid off eventually.
You don?t want to be useless during the eight hours a
day you have to be in front of the keyboard.
* Balance. Find a balance between work, health,
activity, friends, family and hobbies. It will
increase your overall work performance. You lose the
ability to bounce back with age.
* Don?t force alertness. Much like a sleep debt,
forcing alertness with caffeine or other stimulates
will eventually develop a dependency on them to
achieve a baseline state.

Programming Specific Tips: Complexity.
Don?t create more work for yourself than is needed.

* Only code what is needed. If a feature ?might be
useful? then code it later when it is necessary.
* Simplest solution is the best solution. K.I.S.S.
Every line coded is a line that potentially has to be
debugged. Focus your debugging effort on solving the
problem, not on debugging bells and whistles that
don?t contribute to the deadline. More time is lost in
debugging an unnecessarily complex feature then in
designing it.
* Notes to yourself. Put comments in your code
with standard identifiers such as ?TODO? and ?FIXME?
that you can come back to later to add the
improvements you didn?t add the first time. Putting
the date you added that comment is optional, but can
help during a code cleanup (sorry, I mean
?refactoring?) five years later.

Multiple build / project directories.

?Hey, can you check out the latest version of this
file to see if my changes work?'? Except it?s never
just one file, and the changes never work the first
time. Checking code out into your working copy is not
just an interruption, but can lose an entire afternoon
trying to re-achieve the state you were at before
updating that ?one file?. Having multiple directory
trees (hard drive space is cheap) can remove this
problem.

* Working. What you currently have checked out any
are working on. Only checkout code when you?ve already
verified it works using the Stable/Branch directories.
* Stable. The latest valid snapshot/tag of code
that is known to work.
* Branch/Current. The absolute latest checked in
version of all code.

Decompose.

Problems seem more daunting when you can?t see the
trees for the forest. Breaking it up into smaller
tasks not only reduces procrastination, but it also
can increase performance time.

* Design assumptions. Create small unit proofs of
any design assumption upfront so that you know the
design will work before investing time and energy.
* Strawman Integration. When rapidly prototyping a
smaller subset of the design you are pushing the
integration issues until the end. It is best to do an
upfront integration of a strawman of your design to
make sure there aren?t any major gotchas and then
continue with the prototyping.
* Reduce dependencies. Debugging a rapid prototype
can be much faster because you don?t have as many
sources of errors to look at.
* Smallest solution space. Reduce the unit
testbench to only what is necessary to run your
prototype. The goal is to reduce the time between
starting a simulation run and getting results during
development. Keep the inherent downtime in your job
from interrupting your flow. You shouldn?t have time
to think about something other than the problem at
hand (ie: Checking Slashdot. Checking this blog is
ok).
* Symbolic links. Set up the file structure such
that you can run your small unit testbench in parallel
with the main design, ie: symbolically link to where
any files will exist in the real design. It may still
be useful down the road when you want to isolate a
problem.
* Metrics. It is much easier to grab
profiling/coverage metrics from a smaller testbench
that you can iterate many, many times more often then
the main design. The statistics might not be ?real
world?, but they can still be helpful.
* Design for debug. Litter your code with error
assertions when they receive unexpected values or hit
unexpected states. If necessary add a debugging define
so that these assertions can be turned off in the
production code but turned on again when you encounter
a problem. Assertions to test inputs and outputs for
illegal values and raise a big red flag will save you
a lot of time when integrating.

Parallelism.
If you have access to multiple CPUs or a server farm
then use them!

* Pipeline. If the compile/simulate/debug flow has
dead cycles where you are ?waiting for results?, then
you can make use of those cycles by breaking the work
down into distinct units that can be pipelined in
parallel. This keeps you actively solving the problem
instead of getting caught up in procrastination and
servicing interrupts.
* Tracking. Keep a piece of paper (or use your
engineering lab book) beside your desk to write down
reminders of where you left off in the parallel
problems.
* Don?t fire and forget. When you switch to
working on the next task in the pipeline, periodically
check the status on the first task to make sure that
it is running properly.
* Always run something. The goal is to always have
something running in the background while you develop
during the cycles where you would instead be waiting
for results. It could be as simple as seeing if what
you are working on compiles properly while you?re
working on something else.
* Organize. Use tools to keep the multiple tasks
organized such as different workspaces for different
tasks, tabbed terminal windows with different title
bars, saved session views, etc.