I’ve recently noticed that it takes a long time for my bash to load. I’ve found following StackOverflow answer to be useful, and I based my solution to find a startup time hog in my ~/.bashrc upon it.

First off, add following few lines to your /etc/bash.bashrc, ~/.bash_profile, or wherever you’d like to begin tracing the script:

PS4='+ $(date "+%s.%N")\011 '
exec 3>&2 2>/tmp/bashstart.$$.log
set -x

And add following few lines where you want to stop the trace:

set +x
exec 2>&3 3>&-

Now start your bash session (you can simply open a new terminal Window for that). The above will create /tmp/bashstart.<PID>.log. To analyze it, I wrote a little Python script:

import argparse
import heapq

parser = argparse.ArgumentParser(description='Analyze bashstart log for speed.')
parser.add_argument('filename', help='often /tmp/bashstart.<PID>.log')
parser.add_argument('-n', default=20, help='number of results to show')
args = parser.parse_args()
filename, n = args.filename, int(args.n)

with open(filename, 'r') as f:
    q = []
    prev_time = None
    for line in f.readlines():
        line = line.split()
        if '+' not in line[0] or len(line) < 3:
            continue
        text = ' '.join(line[2:])
        seconds, nanoseconds = line[1].split('.')
        time = int(nanoseconds)
        diff = time - prev_time if prev_time is not None else 0
        prev_time = time
        heapq.heappush(q, (diff, text))

for diff, text in heapq.nlargest(n, q):
    print float(diff) / 1000000000, 's:', text

Save it as bashprofile.py, and run it as follows (replace file name with an appropriate):

python bashprofile.py /tmp/bashstart.2831.log -n 20
0.050056909 s: _powerline_init_tmux_support
0.045323022 s: _powerline_setup_prompt
0.044722024 s: _powerline_setup_prompt
0.044423727 s: '[' -f /usr/local/google/home/ruslano/.local/lib/python2.7/site-packages/powerline/bindings/bash/powerline.sh ']'
0.044364097 s: '[' -f /usr/local/google/home/ruslano/.local/lib/python2.7/site-packages/powerline/bindings/bash/powerline.sh ']'
0.044137159 s: _powerline_init_tmux_support
0.015839574 s: __shell_name=bash
0.010850276 s: command which which
0.010105462 s: PS2='\[\]  \[\] \[\]'
0.010000598 s: PS3=' Select variant  '
0.009837956 s: complete -F _svn -o default -X '@(*/.svn|*/.svn/|.svn|.svn/)' svn
0.009767517 s: PS2='\[\]  \[\] \[\]'
0.0095753 s: PS3=' Select variant  '
0.007915565 s: other_utils=(ant automake autoreconf libtoolize make mount patch readlink)
0.00771205 s: for script in version functions/selector cd functions/cli cli override_gem
0.007008299 s: for gnu_util in '"${gnu_utils[@]}"'
0.00693653 s: complete -F _crow crow
0.006803049 s: complete -F _svn -o default -X '@(*/.svn|*/.svn/|.svn|.svn/)' svn
0.006672906 s: for script in version functions/selector cd functions/cli cli override_gem
0.005912399 s: for entry in '${scripts[@]}'

In my example, Powerline turned out to be a massive hog. Looks like I’ll have to troubleshoot the speed or plain disable it.

Don’t forget to remove the lines you added to your bash configuration files after you’re done profiling.

DidYouMean Vim plugin is very simple: it asks you if the file you are trying to open is indeed the right file. How is this useful? Here’s how:

Say you have two files with a similarly starting names: model.py and model_test.py. You type vim mo, you hit tab to autocomplete the name, you hit enter. In vanilla Vim, you’d be opening a new file: model, since that’s where shell’s tab-completion stopped. DidYouMean detects such a nuance and asks you if you wanted to open model, model.py, or model_test.py.

Simple idea, and instantly after trying this out, I would really expect this feature to be included in vanilla Vim.

I enjoy optimizing the way I work: the less time I can spend on something without sacrificing quality - the better. Below are few ideas on the subject of engineering productivity I’ve successfully applied in my career.

Don’t work long hours

A fascinating paper was released in 2011 by a group of Israeli researchers, who studied the factors which affect if prisoners were given a parole or not (source: Extraneous factors in judicial decisions.

First prisoner in a morning has approximately 65% chance of being released. With every next case, the chance dropped significantly, reaching nearly 0% starting with the third case. After returning from a lunch break, odds of a prisoner being released went back up to 65%. And once again, with each new prisoner the odds decline rapidly.

Authors of the paper suggest that making decisions depletes a limited mental facility. People start looking for shortcuts and making mistakes.

Working long hours is something we’ve all done more than once. Be it an upcoming deadline, fascinating problem, or a personal project. The problem with working too long is that you’re doing a poor job without realizing it.

I try to avoid working more than 7 hours a day, and there are people who get an incredible amount of work done under an even shorter amount of time.

This is probably explained by a phenomenon called “ego depletion”: the idea that self-control or willpower draw upon a pool of limited mental resources that can be used up. When the energy for mental activity is low, self-control is typically impaired, which is what is considered to be a state of ego depletion.

Dangers of burning out

Another problem with working too long - is a possibility of a burnout.

A while back I worked as a freelancer for a client of mine. I worked long hours from home office. This was my first time working from home for such a long period of time, and I made a number of mistakes in the beginning. One of which was working too much.

I’ve put in a number of 12-hour marathons in order to get more work done. I was on call most of the time. I became overwhelmed with all the work I had to get done. I started losing interest in work and feeling like things are getting out of my control. Every day felt like a bad day.

Those are the symptoms of a burnout. Feeling of life spinning out of control and feeling like nothing you do makes any impact.

I broke out of a mental prison of a burnout by getting a better work-life balance, enforcing exercise routine, and never working more than 8 hours a day. 7 in most cases.

Work-life balance

Another thing I learned from working from home is how to keep a work-life balance. Not having a separate office and living in a 1-bedroom apartment with my wife, I had to barricade myself in a far corner of a bedroom and turn it into a physically separated office space. That was the space I worked in, and it remained empty after I was done and until I started the next work day.

Work-life balance deserves a special say: it’s the difference between doing an amazing job and going insane. Set aside time and place for work, and never allow a bleed-through. Don’t be on call if you can avoid it. Don’t open or reply to work-related emails at your spare time. Office is for work and home is for family.

Distraction-free environment

Everybody is aware that interruptions hamper productivity, but not everyone actively avoids interruptions during work. Replying to a text message, quickly checking your social network notifications, or looking up that one thing you’ve been forgetting to look up for days - all of this impairs your mental ability to complete the task within a desired time frame and, more importantly, with high quality.

According to various studies it takes from 20 to 30 minutes to get regain the same level of concentration and productivity after a single act of disruption. A 2014 study from George Mason University found that students composed lower quality essays when interrupted only a few times throughout both planning and writing phases. Distracted students performed considerably worse, even though they were given additional time to complete an assignment in order to make up for the interruptions.

Know your tools

Use a single editor well

This is lower level tip than the rest, but something I find utterly important in my daily work. We, the software engineers, spend at least half the time editing some sort of text - code, email, documentation. Taking time to improve the knowledge of the software you use every day pays off.

  • Using Gmail? Learn the keyboard shortcuts.
  • Use Eclispe? Do the same. Search for plugins which can make your everyday work faster and easier.
  • Use command shell for daily work? Practice your shell scripting skills, find the tools that let you do more work with lesser amount of typing.
  • Pick up touch typing. It’s also a part of your toolbox. Why think about keying words in? Lower error rate while typing - you need to go back less.

For instance, I do all my work in shell. I use Tmux for creating and navigating multiple sessions. I use Vim for all my editing needs - code, documentation, blogging, composing long emails (via Mutt). I touch type, so working in a text mode is easy.

Over the years I accumulated aliases for all the frequently used shell commands. All the Vim and Tmux shortcuts are a part of a muscle memory. Jumping from file to file or from one place to another within a file doesn’t take any mental effort and is accomplished with only a couple of keystrokes.

By eliminating the need to think about or spend too much time working with low level concepts - you free up the mental bandwidth for higher level reasoning and problem solving.

Read, don’t stop learning

As per DeMarco and Lister, authors of “Peopleware: Productive Projects and Teams” - one book is more than most programmers read each year. This is the same point Steve McConnell’s “Code Complete” emphasizes.

A lot of programmers don’t read books. A few even don’t follow relevant blogs or websites. Don’t do what software engineers had to do in the olden days: coding by error in isolation from the rest of the industry. Read a book, learn something you don’t know about. A single book read from beginning to end contains wider array of information compared to disjointed articles some programmers limit themselves to.

As Jeff Atwood suggests in his article “Programmers Don’t Read Books - But You Should”, pick up one of the timeless books - not affected by changing technologies and processes.

One of the obscure, but tremendously useful features of Vim is an undo tree. You would expect Vim to have a simple stack for undo and redo actions, but it’s much more complex than that: Vim keeps track of every change you made in the current session, making it possible to access change history beyond basic u and C-r commands.

Default interface for accessing far out branches of the undo tree leaves to be desired, but that’s where Gundo comes in.

Gundo provides an easy to use interface for navigating history branches. In the screenshot above, I am previewing a diff in one of the undo tree branches inaccessible via u command.

As per author’s recommendation, I mapped the plugin to F5, which seems quite convenient to me:

nnoremap <F5> :GundoToggle<CR>

Usage is quite easy. F5 opens or closes the undo tree, j and k are used to travel through changes. Enter key applies the changes.

About a year ago I stumbled upon an article explaining the difference between Vim tabs and buffers. The author emphasized that tabs are merely window layouts, and therefore one-file-per-tab idea I was used to at the moment just wasn’t proper. Instead, author suggested the use of buffer commands to switch between multiple files. I decided to give it a shot, and here are some ideas I would like to share after switching to the use of buffers.

Buffers are open files (they also may not be associated with any files), but they’re not necessarily visible at any given moment. In Vim, windows are not linked to any particular buffer, so you can easily cycle through buffers from within any window.

First and foremost, you probably want to add set hidden to your .vimrc. This option lets you switch between buffers without having to save files.

At it’s basics, you only need few commands for operating buffers:

  • Use :ls to list all buffers for this session.
  • To move between next and previous buffers use :bn and :bp respectively.
  • Use :b partial_buffer_name for navigating to the buffer of your choice. Buffer name auto-complete is supported.
  • You can also use :bN, where N is a buffer number to jump to a specific buffer.
  • Get in a habit of closing buffers you will not use with :bd.

The hardest thing about stopping to use tabs and switching to buffers instead is not having the visual aid: I was used to having a list of files always available at a glance, at the top of my screen. To check what files I’m working on now - I have to hit four keys: :ls (fourth being “Enter”).

Not surprisingly, this taught me to be more mindful about my editing experience. I usually have a clear structure of the files I’m working on in my head. And if the list is getting to long to easily remember, then I’m probably doing something wrong: time to take a break and reset my Vim session.

The experience overall reminded me of my recent switch to blank keyboard key caps: with no inscriptions to aid you, I first felt a bit at loss, especially with they keys I couldn’t find without looking: like function keys or special symbols. But after some time with the blank key caps, I improved my typing skill, and know where even the most obscure characters hide. The switch helped me to improve my typing experience overall.

With Vim, it’s a similar story. After getting past the initial confusion, I achieved high level of awareness about my editing sessions. It didn’t make the editing process any faster, but instead much more satisfying.

But you already new that, since Vim isn’t really about speed.

UPDATE: Made a few corrections and added a :b partial_buffer_name command thanks to /u/___violet___’s Reddit comment.