Your Own Metric System Ian Dees · @undees OSCON 2012 Hello, and welcome. I’m Ian.
By day, I make oscilloscopes. By night, I play guitar irresponsibly.
pragprog.com/titles/dhwcr I also write books, mostly about Ruby topics. A group of us—me, plus two major contributors to the Cucumber test framework—are working on a new book of specific testing techniques. Ruby and its various test frameworks were my gateway drug to code metrics, though for this talk we’ll be concentrating on other languages.
Oscilloscopes have been available commercially since the 1940s. Their architecture changes slowly. Software needs to last, and it tends to last whether we wish for a rewrite or not. Our team’s exploration of this mix of old and new code led to our interest in code metrics.
Setting And even if you’re not working on a large legacy code base, there are likely issues that we face in common.
The forces against us ❥ Entropy drags our code down ❥ Apathy drags us down There are a lot of forces that push on us and our teams. Today, I want to talk about two very di fg erent forces that have surprisingly similar e fg ects: the entropy that drags our code down over time, and the apathy that drags us down personally over time.
Stay engaged and productive How do we fight these forces? How do we keep our interest after our tenth straight hour wading into the weeds of an incomprehensible legacy routine? How do we prevent the code we write today from being someone’s nightmare tomorrow?
Knowing our code can help us do our jobs and have more fun We have many tools in our chest; one is a good set of metrics—information about our code base. My hope is that you’ll consider code metrics at least as an intriguing, low-cost possibility for making the day go by a little better.
Risk #1 Missing or poor information can waste our time or lead us to cause harm The risk with doing this—and there’s always a risk—is that we might waste our time making changes we don’t need, or worse, end up trashing our code in the name of blindly satisfying some target number.
Two steps forward 1. Ask questions about your code 2. Choose metrics that answer those questions How do we address that risk? By letting our project needs dictate our metric choices, not the other way around. It sounds simple. But as we’ll see, it’s possible to misapply a metric and make a big mess.
Purpose of metrics Since getting the reasons right is so important, let’s talk about why we’re gathering this data.
purpose of metrics Help you answer a question The purpose of any metric should be to help you answer a question. Since we’re developers who maybe also do a little testing, let’s ask a few example questions now.
purpose of metrics What mess should I clean up next? For example, if several files need some love, where should I concentrate my e fg orts?
purpose of metrics The product backlog isn’t a substitute for your brain Something else may be giving us guidance on what part of the code to work in—like the product backlog. But you may be in a situation where you’ve got a little more leeway, like an explicit charter to pay down technical debt.
Risk #2 Making structural changes can introduce new bugs (or expose existing ones) That said, when you do wander o fg the map, you do risk creating a bug. With legacy code, you may also uncover an existing bug and get the blame nonetheless. One way to address this risk is to improve your test coverage, and make small changes at a time. Another is to choose the right metrics; fixing static analysis warnings has anecdotally been one of the lowest-risk change activities I’ve ever seen.
purpose of metrics Where are the bugs (likely to be)? Here’s another question we might ask. Where are the bugs? Where are the old bugs we haven’t found yet? Where are the new ones we might have created recently?
purpose of metrics /** * REMOVE THIS CODE * BEFORE WE SHIP! */ We can also turn to our code for ideas of what questions to ask. Has anyone seen something like this comment in production code? The number of these red flags in your code is a kind of code metric you can measure and reduce.
purpose of metrics Have we forgotten anything for this release? That quantitative measurement—number of bad comments in the code—is helping us make a qualitative determination.
purpose of metrics These questions are for us The questions we’ve heard so far are things we might ask,...
purpose of metrics Not for someone else ...not things someone else might ask.
purpose of metrics Questions from others: (outside the scope of our metrics) Not that other people’s questions aren’t legitimately interesting, or that they might not apply metrics of their own.
purpose of metrics Should we hold the release? For example, the SQA team might be looking for red flags that could hold up the release.
purpose of metrics errors/KLOC → time → So they might look at aggregate errors per thousand lines of code. Not something I necessarily use to make decisions as a developer, but it doesn’t scare me if this metric is in use somewhere.
purpose of metrics Who’s got the best KLOC or error rate? On a more sinister note, tracking rates of code production or error creation/resolution are outright destructive of teams.
purpose of metrics It was time to fill out the management form for the first time. When he got to the lines of code part, he thought about it for a second, and then wrote in the number: -2000. After a couple more weeks, they stopped asking Bill to fill out the form, and he gladly complied. —folklore.org There was apparently a brief, dark time at Apple when employees were tracked by lines of code produced, until Bill Atkinson showed that you can improve and shorten the code at the same time.
purpose of metrics Have we met our target complexity or coverage? Another, more subtle trap is setting absolute thresholds for various metrics.
Doing so is like blindly obeying a GPS device: sooner or later, you’ll drive o fg a cli fg .
purpose of metrics Metrics serve you, not the other way around Metrics are supposed to be here for our benefit.
purpose of metrics Keep the job fun And indeed, in addition to answering specific questions about our projects, they can make coding seem a little bit like a game where the side e fg ect is to produce better code...
purpose of metrics More fun than actually working? ...as long as we still get around to writing the code eventually.
Risk #3 There is a trap here for the distractible We have to be careful not to spend all day writing fancier shell scripts and slapping our stats onto elaborate dashboards (though there are quick-and-cheap dashboards I like; see the Tranquil project).
Common metrics Now that we have a few questions in mind about our code base, let’s look at some metrics commonly used by many projects. (Later, we’ll look at writing our own.) The nice thing about prefab metrics is that we can find open source implementations and supporting research.
common metrics Languages ❥ C: a case study ❥ Perl: the beginner’s experience ❥ <your lang> just ask! Rather than present you with a laundry list, I’m going to stick to a few targeted examples in C and Perl. But similar tools likely exist for your language; catch me in the hall afterwards if you’d like to explore that together.
common metrics Repo for this talk github.com/undees/oscon The code samples you’re about to see are on GitHub; feel free to send a pull request if you’d like your favorite language to be included.
common metrics Cyclomatic complexity The granddaddy of modern code metrics is McCabe Cyclomatic Complexity. It’s meant to be a loose measure of how many di fg erent paths there are through a piece of code.
common metrics E – N + 2P The fancy explanation is that you draw a graph of control flow through your function, then calculate a score from the number of edges, nodes, and return points.
common metrics 1. Start with a score of 1 2. Add 1 for each if, case, for, or boolean condition The simpler explanation is that we walk through the code and add a point for each decision the code has to make.
Volume speaking_volume( bool correct_room, bool correct_time) { if (correct_room && correct_time) { return INTELLIGIBLE; } else { // rehearsing return INAUDIBLE; } } complexity: 1 So we’d start with a value of 1 for this code sample...
Volume speaking_volume( bool correct_room, bool correct_time) { if (correct_room && correct_time) { return INTELLIGIBLE; } else { // rehearsing return INAUDIBLE; } } complexity: 2 ...add 1 point for the if statement...
Volume speaking_volume( bool correct_room, bool correct_time) { if (correct_room && correct_time) { return INTELLIGIBLE; } else { // rehearsing return INAUDIBLE; } } complexity: 3 ...and add 1 final point for the boolean operator. Depending on the implementation, we might add a point for the multiple returns.
common metrics pmccabe parisc-linux.org/~bame/pmccabe One easy-to-use implementation of this metric for C code is pmccabe.
Recommend
More recommend