People fear that an underlying assumption behind PairProgramming
For any programmer, no matter how good he or she is, if we get someone else to sit with them, the value of their work will double.
In other words, for PairProgramming
to make economic sense, a pair must deliver at least twice the value that an individual would deliver in the same period of time. By "value" I mean some hard-to-define combination of features, quality, maintainability etc -- i.e. the sum total of what programmers get paid to create. Whatever "value" is, we should get at least twice as much of it from a pair than an individual, otherwise its not worthwhile to pair them up.
Doubters ask, "But is this really possible? Is it really possible to double the output and/or quality of even the best programmers?"
The underlying assumption is actually, For any two programmers, no matter how good he or she is, if we get them to sit together, the value of their work will be greater than if they sit apart.
Even the best programmers make mistakes, overlook typos, make false assumptions, get stuck on issues. Any competent, even if inexperienced, programmer can help with these. The "value" produced by programming is more than just the typing.
The "value" being created is the value of the team, not of individual programmers. If your team consists of one really great programmer and a bunch of mediocre ones, it may be true that the "value" output of the great programmer paired with the mediocre one is less than twice that of the great programmer, but is likely to be greater than the sum of the "value" outputs of the great and mediocre programmers working individually.
The expressed fear seems to assume that two programmers are doing one programmer's worth of work. This is not the case. The two programmers are still doing two programmers' worth of work, they're just doing it together rather than individually.
Pair programming is a learned skill. It takes time and work to do it well. It also pays off more and more over time. There are benefits beyond the "value" currently being produced. The team communication and mutual learning aspects also provide great benefits.
But, if you're accomplishing the same tasks in the same amount of time with higher quality and using the same programmers, where is the "cost of pairing"?
still un-refactored thread mode:
There's an implicit assumption there that all bugs take the same amount of time to fix. In my experience, this is very much false. When I program without unit tests or a "smart" (syntax-checking) editor, the distribution usually looks like this:
- 4 hours to write the code.
- About 6-12 bugs that can be fixed in under 10 minutes. Syntax errors, type mismatches, nulls, and general brain farts.
- About 2 bugs that take an hour each
- 1 bug that takes 8-10 hours.
Unit tests tend to smooth out the distribution a bit - I don't get the multi-day bugs as much, though I get more that show up and can be fixed in 5-10 minutes. And syntax-aware editors cut down the the number of "stupid" errors dramatically. But my point is that bug fixing time is a ScaleFreeDistribution?
, akin to the EightyTwentyRule
, not a constant. And like any skewed distribution, you get best results by concentrating on the outliers.
Let's say that Alice is a GrandMasterProgrammer
who can make 95% of the tests pass within 4 hours. Let's also say that Bob is a LessAbleProgrammer
who can make 80% of the tests pass in 8 hours. We'll forget about the minor bugs, syntax errors, etc. and lump them in with those times. The interesting part is what happens with the remaining 5/20% of the tests. If we observed the EightyTwentyRule
literally, this would suggest that Alice's 5% would take a full work week, 40 hours, to complete. This is probably excessive, so lets make the more generous (and probably fairly realistic) assumption that Alice's 5% takes an additional 12 hours to complete, and Bob's 20% takes 72 hours to complete. Net productivity over 2 weeks is 5 units from Alice (2 days apiece), and 1 unit from Bob (10 days apiece).
Now, I'm about to make a crucial assumption: that Alice and Bob's "difficult tasks" are disjoint, such that what's difficult for Alice is not necessarily difficult for Bob and vice-versa. This will undoubtedly be controversial, because people think of some programming tasks as "difficult" and others as "easy". But it squares with my experience, which is that AllProgrammingTasksAreEasyOnceYouveSolvedThem?
, and solving them is really just a matter of coming at it from the right angle. I recently spent a full workday tracking down a bug that was introduced by overwriting a setting in a config file. If I'd been paired with someone who'd installed the software more often, that could've been caught in 2 minutes. Similarly, I've paired with more experienced programmers that go "WTF? How could it be giving that
answer" where I just say "Swap those two lines around", and bug is fixed.
A pair works at the speed of its slowest member, so it take at least 8 hours for them to finish the "easy" coding. Probably more, when you figure in communication overhead. But the "tough" bugs are only those that neither
Alice nor Bob could solve, so they only comprise 0.2 * 0.05 = 1% of bugs. In 8 hours, Alice and Bob together get 99% of the tests passing. Figure 3 hours to finish the last bug; this is on the high end of Alice's rate, reflecting communication overheads and giving some leeway on the "difficulty is personal" assumption. In the end, it takes Alice + Bob 11 hours to finish the user story together, so they finish just over 7 units in the 2 week period. Even though Alice now works twice as slowly, they end up getting an extra work unit done because they waste far less time with difficult tasks. -- JonathanTang
Interesting analysis. What if Alice really hates working more slowly? Is it worthwhile to cut the job satisfaction of your GrandMasterProgrammer (s) just to get an increase of one work unit?
Another thought: Alice alone can produce 5 units in 2 weeks. Bob adds one extra unit if he works on his own. But, if we pair him with Alice we can consider his contribution, perhaps a bit generously, to be two units. In other words, his contribution is, at best, 40% of Alice's. Will his salary be, at most, 40% of Alice's? If its more than that, do we conclude that it would be more economically efficient for Alice to do all the work by herself?
Again, we run into difficulties because economics is non-linear.
It is almost always more economically efficient to hire one GrandMasterProgrammer
than an army of LessAbleProgrammer
s, regardless of what methodology you use. Aside from productivity differences, there are communication costs (which rise as N^2 where N is the number of programmers), benefits, office space, legalities, and all other sorts of overhead. PaulGraham
goes into this extensively on his web site; he did this with ViaWeb?
also describes it in TheMythicalManMonth
, where he suggests organizing groups like a surgical team, where one highly-skilled programmer does all the coding.
But there's only so much that one person can do. There are 24 hours a day; you're obviously not going to get more work out of your GrandMasterProgrammer
than that. Long before that, you run into problems because people's productivity decreases pretty sharply with number of hours worked. Much more than a FortyHourWeek
and your GrandMasterProgrammer
won't be a grandmaster anymore. Anecdotally, I suspect that the optimum is a KelloggWorkWeek
, but there are cultural forces against that.
So at some point you have
to hire other programmers. Say that there are 6 units of work to be done. At that point, it may just be better to pay Alice 40% more and have her work 10 hour days (this is 25% rather than 20% longer because of lesser efficiency past 8 hours, and it's 40% more pay rather than 25% because of overtime. Although most programmers are exempt employees, you better be paying them more if you expect them to work sustained long hours). But then say that there are 7 units of work. You can't just have Alice work 14 hour days because she'll quit. You have to bring on another programmer. And you won't hit your production targets anyway unless you pair them.
(In fact, this is what happens at many corporations. They bring on another programmer who's significantly less skilled than the original, and find that they're getting less
done than with their original staff. Even if the programmer is skilled, there are still communication and training costs. Hence the conventional wisdom that "Adding more people to a late project makes it later.")
This all assumes that you get paid for 7 units of work if you complete 7 units, and you get paid nothing if you complete 6 units. This is what most software is like: giving the customer a half-finished version isn't very good. XP may alleviate it somewhat with its continual releases and prioritized incremental development, though. -- JonathanTang
It is, supposedly, a "fact" that programmers differ in productivity by at least an order of magnitude. Let's assume that fact is true for the purposes of this discussion. Say we have two programmers, Alice and Bob. Alice is a "top gun". In a typical day, she produces 100 "units" of "value". Bob is at the lower end of the scale. In one day, he produces 10 units of "value"
Let's say we pair them. (I know that, ideally, PairProgrammingIsDoneByPeers
. More on that below.) You say that, in a typical day, the pair will produce more than 110 units of value.
I suggest that, when differences of this magnitude exist, the pair will actually accomplish less
than what Alice would have done on her own. Alice will have to pause to explain things to Bob. More importantly, Alice will suggest things that Bob objects to. Bob objects because he can't understand them, therefore he labels them as "too hard".
This leaves Alice a difficult choice. Does she just steam-roll over Bob's objections and go ahead anyway? That's not good for team morale and beside, if Bob doesn't understand what's going on he can't offer much in the way of constructive comments. So, does Alice back off from her suggested approach. Does she intentionally suggest an inferior approach, just so that Bob will understand it? Does she do this knowing that the inferior approach is flawed, and will have to be refactored to the more difficult one later...? Does she simply ask Bob for his ideas? Does Bob try is ideas out only to find that they don't quite solve the problem at hand? Or possibly worse, they do solve the problem but they incur an on-going TechnicalDebt
, some side effect that makes the code harder to maintain or re-use. Something which Alice's solution would have avoided (after all, that's why she's so productive, since she has the vision to avoid running up too much TechnicalDebt
is not quite the right term to use here. I mean some small penalty, in terms of ease of use, clarity, maintainability etc which you pay each time you call the code that Alice and Bob have written. Alice knows that the penalty will be paid, because she knows how much better their code could have been. Bob doesn't understand that, and so thinks that their paired design has no downside at all.)
Readers of this page might say that, by pairing, Alice will help Bob to lift his performance. Perhaps that's true to some extent, but I suspect that the productivity differences found in research have more to do with innate ability than experience or training. In fact, in terms of years of experience, training and other easily-measurable criteria, Alice and Bob may appear to be a well-matched pair.
If Alice and Bob can't work together, you have problems that neither pairing nor not-pairing can solve. These are people issues, not coding issues. If Bob is innately incapable of improved productivity (which I find hard to believe), why keep him on the team at all? Why would Alice abandon what she knows to be a better (simpler in Kent's terms) just to appease Bob's inexperience? Why would Bob expect all coding to be at the level of the lowest programmer? Does he think that he's really the better programmer? Is there no coach to instill a sense of what is better?
Also keep in mind that pairs are not married to each other. They should pair for a few hours and then switch around. This cross-fertilization will do wonders for developing a shared understanding of "goodness" amongst the team. Most people want to do better and, while they may mistake what is better with respect to one person with whom they have a personality conflict, will understand the consensus of what is better. Granted, if you have one Alice and a team full of Bobs who have inflated opinions of themselves, you might get into a pathological case where the Bobs conclude that Alice is the laggard, or otherwise undesirable. If that's the case, maybe Alice should get out--the project seems doomed.
PairProgramming is not a mechanical arrangement. It's a collaboration between two people who are fully engaged with the task at hand. If it's not, you should investigate what's going on and try to solve that problem. As I say, it's a people issue.
I'm not sure that forcing people to adopt a process they are uncomfortable with is a "people issue." Maybe PairProgramming
may be effective with two people who are committed to the process, but the economics change drastically when one or both of the people do not believe in the process or do not know how to do it. I would not prevent programmers from PairProgramming
if they want to, but likewise, I would not force those who want to code solo from doing that either. I feel I can trust my team members to code effectively without me or someone else watching over their shoulders.
If people cannot work effectively with other people on the team, it's a "people issue." You can approach such a people issue by assigning tasks to non-team-players that do not require them to interact with other team members. You can reject teamwork wholly, too. These things have nothing to do with PairProgrammingEconomics, however.
I am not sure that being uncomfortable with pair programming is equivalent to "cannot work effectively with other people on the team." Most solo programmers I have known can work well with others, but that does not mean that they enjoy having someone look over their shoulders while they are programming. The economics are quite simple, if the people do not enjoy pair programming and are being forced to do it, it seems logical that they will be less productive. From my experience, they become less productive than either one alone (i.e., less than half of their combined solo production).
Pair programming is more than/different from "having someone look over their shoulder." It is teamwork and collaboration. Nevertheless, if you can't or won't do it, you can't or won't do it. That has nothing to do with economics.
It has everything to do with economics. One cannot determine the economics of pair programming based on some idealized set of programmers; the economics must be based on the actual programmers available. If pair programming is being proposed as a universal solution, it needs to be universally applicable. The basic question is, "Is pair programming economically viable for all programmers?" If the answer to the first question is no, then the following questions arise, "For what subset of programmers is pair programming economically viable?" and "What are the economic advantages within that subset?"
As long as pair programming remains a poorly defined development approach, people will continue to fail (i.e., spend more time and manpower while generating ill-feelings) when attempting it. This in itself indicates that pair programming is not economically justifiable for general application.
You could say that programming is not economically justifiable because it's not economically viable for all people. (P.S. Pair programming is not "poorly defined.")
You're asserting that, as long as both programmers have the right attitude, they'll deliver more value as a pair than as separate (but collaborating) individuals. This page is all about asking, "Is that really true? Always?
If the XP movement to says that's true, always, then the XP movement is making a very strong claim, and I'd like to see the evidence.
To me, it seems self evident that while the claim might be true very often, it's probably not true always
Actually, the assertion appears to be the reverse, if the pair does not deliver more value when pair programming, the individuals are personally at fault. As someone who believes pair programming works in some cases but not in others, I find this type of argument troubling. I am much more interested in find out how and when pair programming works and not so much in blaming someone when it does not. -- AnonymousCoward
While there are lots of great comments re the people aspects on this page, the original question here was really, "Are there some people who are just so darn good that its pointless to pair them?"
Is it appropriate to pair people of the caliber described here: http://www.paulgraham.com/gh.html
. If so, who do you pair them with?
And if you do pair these people, do they find it difficult to perform at their best? (See PairedGeniusDiscussion
Imagine a high productivity programmer, paired with a low productivity one. Imagine that the high productivity programmer finds that her output drops by 30% as a result of being paired. Imagine that the low productivity programmer finds that his productivity is actually doubled by being in a paired situation. That's great, but with a wide disparity in productivity, that's still not enough to make up for the 30% lost from the GrandMasterProgrammer
But it would be if you were rotating pairs frequently, so your one grandmaster was actually doubling the output of five other team members, and, over weeks and months, raising their long-term ability too.
What about the nature of the domain? Some domains are far more sensitive to accuracy/bugs than others. Further, what about pairing of the "problem" programmers rather than all programmers? My experience is that some programmers are pretty good and reliable on their own such that a second pair of eyes won't improve their quality score enough to justify a second pair of eyes. Fix what's broke instead of fix what's fixed.
There are some people who, if their outputs are doubled, reduce the output of the team. Get rid of those with negative productivity. It will make your analysis of pair programming much easier.
See also: PairProgrammingGoneBad