    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Debug Complexity: How Assertions Affect Debugging Time</title>
        <link>https://members.accu.org/index.php/articles/2018</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #123 - October 2014</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c342/">o123</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-342/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+342/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Debug Complexity: How Assertions Affect Debugging Time</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 07 October 2014 21:41:16 +01:00 or Tue, 07 October 2014 21:41:16 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Debugging any program can be time consuming. Sergey Ignatchenko and Dmytro Ivanchykhin extend their mathematical model to consider the effect of assertions.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Disclaimer: as usual, the opinions within this article are those of â€˜No Bugsâ€™ Bunny, and do not necessarily coincide with the opinions of the translators and editors. Please also keep in mind that translation difficulties from Lapine (like those described in [<a href="#[Loganberry04]">Loganberry04</a>]) might have prevented an exact translation. In addition, the translator and <em>Overload</em> expressly disclaim all responsibility from any action or inaction resulting from reading this article.</p>

<p>In â€˜A Model for Debug Complexityâ€™ [<a href="#[Ignatchenko13]">Ignatchenko13</a>], we started to build a mathematical model for estimating debugging efforts, and made some sanity checks of our model, in particular on relations between coupling and debug complexity. In this article, we have extended that model to see the effect of the assertions on debugging time. It should be noted that, as previously, the model should be considered to be very approximate, with several assumptions made about the nature of the code and debugging process (though weâ€™re doing our best to outline these assumptions explicitly). Nonetheless, the relations observed within the results obtained look quite reasonable and interesting, which makes us hope that the model weâ€™re working with represents a reasonable approximation of the real world.</p>

<h2>Assumptions</h2>

<ol>
	<li>In â€˜A Model for Debug Complexityâ€™ [II2013], we considered purely linear code. However, it seems that in the context of debugging the same analysis applies to arbitrary code, as long as the execution path is fixed (which is usually the case for deterministic, repeatable debugging); in this case the execution path can be interpreted as linear code for the purposes of analysis. In this article, weâ€™ll use the term â€˜linear codeâ€™, implying that it is also applicable to any execution path.</li>

	<li>The linear code consists of (or the equivalent execution path goes through) <em>N</em> lines.</li>

	<li>In a naive debugging model, the developer goes through the code line by line, and verifies that all the variables are correct. <strong>T</strong><sub>singlecheck</sub> denotes the time to check a single variable.</li>

	<li>In the earlier article, we mentioned that in many cases it is possible to use a bisection-like optimization to reduce debugging time very significantly. However, such an optimization requires well-defined interfaces to be able to check the whole state of the program easily, and in such cases individual test cases can be easily built to debug an appropriate program part. For the purposes of this article, we will only consider a chunk of code which cannot easily be split into well-defined portions (in other words, a â€˜monolithicâ€™ chunk of code), and will not analyze it using bisection optimization.</li>

	<li>Previously, it was mentioned that not all variables need to be analyzed due to coupling. For the purposes of this article, weâ€™ll use the term â€˜variables to be analyzedâ€™; also we expect that for our analysis of chunks of code which cannot be easily split (see item 4 above), the chances of tight coupling are rather high, so the difference between â€˜variablesâ€™, â€˜variables to be analyzedâ€™, and â€˜coupled variablesâ€™ is not expected to be significant enough to substantially affect the relations observed within our findings.</li>

	<li>We assume that the number of variables to be changed grows from the beginning to the end of the code; to simplify modeling we also usually assume that this growth is linear.</li>

	<li>In the earlier article, an obvious optimization â€“ that after the bug is found, the process of going through the code line by line can be stopped â€“ wasnâ€™t taken into account. However, we feel that it doesnâ€™t substantially change relations observed within our  findings, and as taking it into account will complicate the mathematics significantly, weâ€™ll leave such analysis for the future.</li>

	<li>Our analysis is language-independent. That is, all language-specific effects such as â€˜in C/C++ you can easily write an assert such as <code>assert(a=b)</code> which will cause bugsâ€™, are out of scope. Also, weâ€™ll use the term <code>ASSERT</code> for assertions in any programming language.</li>
</ol>

<table class="sidebartable">
	<tr>
		<td class="title">Notation</td>
	</tr>	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td><em>N</em></td>
					<td>The total number of lines in a â€˜monolithicâ€™ code chunk</td>
				</tr>
				<tr>
					<td><em>x</em></td>
					<td>The current line</td>
				</tr>
				<tr>
					<td><em>v(x)</em></td>
					<td>The number of variables to consider at line <em>x</em>; <em>v(x) ~ k*x</em> for some <em>k</em> (see <em>Assumption #6</em> above)</td>
				</tr>
				<tr>
					<td><em>w(x)</em></td>
					<td>The amount of work spent on a single line to analyze variables; as  discussed in â€˜A Model for Debug Complexityâ€™ [<a href="#[Ignatchenko13]">Ignatchenko13</a>]

					<p style="margin-left:1em">
						<img style="max-width:25%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-01.png" />
					</p>

					</td>
				</tr>
				<tr>
					<td><em>W(N)</em></td>
					<td>The total amount of work for debugging a single bug in a code of length <em>N</em>; as it was shown in â€˜A Model for Debug Complexityâ€™:

					<p style="margin-left:1em">
						<img style="max-width:35%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-02.png" />
					</p>

					<p>This sum may be estimated converting to integrals:</p>

					<p style="margin-left:1em">
						<img style="max-width:40%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-03.png" />
					</p>

					<p>which is, if <em>N</em> is large enough is</p>

					<p style="margin-left:1em">
						<img style="max-width:25%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-04.png" />
					</p>

					<p>with some coefficient <em>k<sub>1</sub></em>. That is, it grows exponentially with the length of code (NB: we do not consider bisection-like optimization, see <em>Assumption #4</em> above).</p>

					</td>
				</tr>
			</table>
		</td>
	</tr>

</table>

<h2>Introducing ASSERTs</h2>

<p>Now assume that there is an <code>ASSERT</code> that catches the bug, defining â€˜an <code>ASSERT</code> that catches the bug <em>X</em>â€™ as â€˜an <code>ASSERT</code> which fails if bug <em>X</em> is presentâ€™.</p>

<p>If the <code>ASSERT </code><em>A</em> is at line <em>x</em><sub>A</sub>, then it remains to debug only the first <em>x</em><sub>A</sub> lines, and the amount of work required will be </p>

<p style="margin-left:1em">
	<img style="max-width:20%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-05.png" />
</p>

<p>It should be pointed out that the ratio of the amount of work without this <code>ASSERT </code><em>A</em>, compared to that with it, will be </p>

<p style="margin-left:1em">
	<img style="max-width:14%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-06.png" />
</p>

<p>This suggests, in particular, that an <code>ASSERT</code> in the middle of code can save far more than 50% of the work.</p>

<p>For instance, in a one-thousand line code chunk with 10 variables to be analyzed at the end (that is, <em>N</em>=1000, and <em>k</em>=0.01) the total amount of work without asserts may be of the order of </p>

<p style="margin-left:1em">
	<img style="max-width:69%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-07.png" />
</p>

<p>And with the <code>ASSERT</code> in the middle of the code this value will become</p>

<p style="margin-left:1em">
	<img style="max-width:65%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-08.png" />
</p>

<p>which is 33 times less!</p>

<p>In practice, an <code>ASSERT</code> may catch a bug with some probability: one may assume that checking a certain condition in the <code>ASSERT</code> will catch the bug, but indeed, may not. Letâ€™s say that an <code>ASSERT</code> has a probability <em>p</em><sub>A</sub> of catching a bug. Then, the expectation of the amount of work may be estimated as a sum of</p>

<p style="margin-left:1em">
	<img style="max-width:40%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-09.png" />
</p>

<p>where the first term is for the case when the <code>ASSERT</code> is successful, and the second term is for the opposite case.</p>

<h2>Quality of ASSERTs</h2>

<p>Clearly, the greater the probability of an <code>ASSERT</code> catching the bug, the less debugging work has to be done. But is it true that an <code>ASSERT</code> with probability of catching a bug of, say, 0.3 is only twice as bad than that with probability 0.6? If two <code>ASSERT</code>s are independent and have a probability of catching a bug of 0.3, then the probability that the bug wonâ€™t be caught by either of them is (1-0.3)<sup>2 </sup>= 0.49.  Letâ€™s use the above example, and assume that all <code>ASSERT</code>s sit in the middle of the code. Substituting, we may get for the <code>ASSERT</code> with probability 0.6:</p>

<p style="margin-left:1em">
	<img style="max-width:80%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-10.png" />
</p>

<p>And for two <code>ASSERT</code>s with probability 0.3 each:</p>

<p style="margin-left:1em">
	<img style="max-width:80%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-11.png" />
</p>

<p>Letâ€™s define an â€˜assert which has a high probability of catching probable bugsâ€™ as a â€˜high-quality assertâ€™. Unfortunately, there seems to be no simple recipe on â€˜how to write high-quality assertsâ€™, though one consideration may potentially help: if an assert aims to catch one of the most common bugs it has quite a good chance of being a â€˜high-quality assertâ€™. In particular, â€˜No Bugsâ€™ has observed that, when coding in C/C++, simple assertions, say of an array index being within the array boundaries, are extremely rewarding in terms of helping to reduce debugging times â€“ simply because it is very easy to go beyond allocated memory, and it is very difficult to find the exact place where this has happened. Another potential suggestion is related to using asserts as a way of (enforced at runtime) documenting code [Wikipedia]; such â€˜code documentingâ€™ asserts (in the experience of â€˜No Bugsâ€™) tend to catch more subtle logical bugs.</p>

<h2>Multiple bugs</h2>

<p>In general, <code>ASSERT </code><em>A</em> may catch more than a single bug, and we may talk about the probability <em>p</em><sub>A</sub><sup>B</sup> of the <code>ASSERT </code><em>A</em> catching a specific bug <em>B</em> residing in the code. Thus, if there are <em>n</em> bugs, then <code>ASSERT </code><em>A</em> may have probabilities <em>p</em><sub>A</sub><sup>Bi </sup>of catching bug <em>Bi</em> for each <em>i</em> from 1 to <em>n</em>. With this assumption, for instance, the probability that <code>ASSERT </code><em>A</em> is useless is the product:</p>

<p style="margin-left:1em">
	<img style="max-width:14%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-12.png" />
</p>
<p>We may call this product the value ineffectiveness of an <code>ASSERT</code>. It is clear to see that if, with time, some bugs are caught and therefore the number of bugs decreases, the value ineffectiveness of <code>ASSERT</code>s tend to increase. Letâ€™s denote it by <em>IL</em>. The complimentary probability, 1-<em>IL</em>, gives a chance that the <code>ASSERT</code> catches at least one bug.</p>

<h2>Multiple bugs â€“ multiple ASSERTs</h2>

<p>In a real program, there is often (alas!) more than a single bug, and it is (luckily!) possible to place more than a single <code>ASSERT</code>. Then the amount of work to catch a single bug in a code with <em>n</em> bugs and <em>m</em> <code>ASSERT</code>s placed at lines <em>x</em><sub>i</sub>, respectively, may be estimated (assuming for simplicity that <code>ASSERT</code>s are enumerated in the order of lines they are placed at) as:</p>

<p style="margin-left:1em">
	<img style="max-width:68%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-13.png" />
</p>

<p>For instance, in the above example with three <code>ASSERT</code>s at lines 250, 500, and 750, respectively, and values of ineffectiveness of 0.5 each, to catch a single bug the amount of work will be:</p>

<p style="margin-left:1em">
	<img style="max-width:77%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-14.png" />
</p>

<p>which is more than 6 times less than without any <code>ASSERT</code>s.</p>

<p>To illustrate the effect of using asserts from slightly different point of view, for simplicity we may make another assumption that for any <code>ASSERT</code> the probability <em>p</em> of catching any specific bug is the same:</p>

<p style="margin-left:1em">
	<img style="max-width:16%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-15.png" />
</p>

<p>Then in the above notation, the value of ineffectiveness <em>IL</em> may be written as a function of number of remaining <em>k</em> bugs:</p>

<p style="margin-left:1em">
	<img style="max-width:17%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-16.png" />
</p>

<p>Then, using (*) above, we may calculate the work for finding a bug when only <em>k</em> bugs remain:</p>

<p style="margin-left:1em">
	<img style="max-width:71%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-17.png" />
</p>

<p>Adding up the amounts of work <em>W</em>(<em>k</em>) for each <em>k</em> from <em>n</em> to 1 will give us a total expected amount of work to debug all <em>n</em> bugs:</p>

<p style="margin-left:1em">
	<img style="max-width:14%" src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Eqn-18.png" />
</p>

<p>To get some taste of what these formulae mean, we have calculated a few samples based on the example that we considered above: a chunk of 1000 lines of â€˜monolithicâ€™ code, a linear increase of the number of  variables to be analyzed along the code from 1 to 10, 5 bugs, and certain number of <code>ASSERT</code>s with a bit more realistic probability of catching a bug of 0.02; the resulting graph of â€˜cumulative amount of work as debug progresses through finding bugsâ€™ is shown on Figure 1.</p>

<table class="sidebartable">
	<tr>
		<td><img src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Ignatchenko-Ivanchykhin-01.png" /></td>
	</tr>
	<tr>
		<td class="title">Figure 1</td>
	</tr>
</table>

<p>In particular, this graph illustrates that, as we have mentioned above, the <code>ASSERT</code> effectiveness tends to â€˜degradeâ€™ as debugging goes ahead. This finding is consistent with what we observe in practice, where catching â€˜the last bugâ€™ will usually require far more work than the first one. One way that is derived from practical experience, and which follows from the above reasoning, is to add <code>ASSERT</code>sâ€¦ or to follow a good habit of using them in any place where conditions may be in doubt whilst coding.</p>

<p>Another example of calculation is shown on Figure 2 and illustrates how increasing the number of <code>ASSERT</code>s helps to reduce amount of work necessary to debug the program (note that for presentation purposes, the number of <code>ASSERT</code>s on the graph is near-logarithmic).</p>

<table class="sidebartable">
	<tr>
		<td><img src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Ignatchenko-Ivanchykhin-02.png" /></td>
	</tr>
	<tr>
		<td class="title">Figure 2</td>
	</tr>
</table>

<p>Note that while the nature of our analysis is very approximate, the relations observed within our results are expected to be reasonably close to reality; that is, while real-world debugging time can easily differ from the results calculated using our formulae, reduction of the real-world debugging time as number of <code>ASSERT</code>s increases, should be reasonably close to those calculated and shown on the graphs.</p>

<h2>Conclusion</h2>

<p class="quote">Good is better than bad,Happy is better than sad,My advice is just be nice,Good is better than bad</p>

<p class="quote"><em>~ Pink Dinosaur from </em><em>Garfield and Friends</em></p>

<p>Within the debug complexity model previously introduced [II2013], we have analyzed the impact of asserts on debugging time. Our results seem to be quite consistent with debugging practice: </p>

<ul>
	<li><code>ASSERT</code>s can reduce debugging time dramatically (making it several times less)</li>

	<li>debugging-wise, there are â€˜high-quality assertsâ€™ and â€˜not-so-high-quality assertsâ€™</li>

	<li>purely empirical suggestions for â€˜high-quality assertsâ€™ were given in the â€˜Quality of ASSERTsâ€™ section</li>

	<li>the time for debugging â€˜the last bugâ€™ is significantly higher than the time for debugging the first one.</li>
</ul>

<p>In addition, it should be noted that the impact of <code>ASSERT</code>s on the program is not limited to a reduction in debugging time. As such effects are well beyond the scope of this paper, weâ€™ll just mention a few of them very briefly. On the negative side: depending on the programming language (and especially for the languages where an <code>ASSERT</code> is a mere function/macro, such as C/C++) it may be possible to write an <code>ASSERT</code> which changes the state of the program (see also <em>Assumption #8</em> above). On the positive side, <code>ASSERT</code>s can be used to create documentation of the program, where such documentation (unlike, say, comments) cannot become out of date easily.</p>

<p>Overall, â€˜No Bugsâ€™ highly recommends the using of <code>ASSERT</code>s, though feels that creating any kind of metrics such as â€˜number of <code>ASSERT</code>s per 1000 lines of codeâ€™, as a result of Goodhartâ€™s Law [<a href="#[Goodhart]">Goodhart</a>], will become as useless as â€˜number of comments per 1000 lines of codeâ€™. As <code>ASSERT(1==1)</code> is as useless as it gets, it is certainly not about sheer numbers, so it is important to use high-quality <code>ASSERT</code>s. This still seems to be an art rather than science, though a few hints for â€˜high-quality <code>ASSERT</code>sâ€™ were provided above, and most likely there are many more other such hints in existence.</p>

<p><img src="http://accu.org/content/images/journals/ol123/Ignatchenko-Ivanchykhin/Ignatchenko-Ivanchykhin-03.png" /></p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Goodhart]"></a>[Goodhart]  <a href="http://en.wikipedia.org/wiki/Goodhart%27s_law">http://en.wikipedia.org/wiki/Goodhart%27s_law</a> </p>

<p class="bibliomixed"><a id="[Loganberry04]"></a>[Loganberry04] David â€˜Loganberryâ€™, Frithaes! â€“ an Introduction to Colloquial Lapine!, <a href="http://bitsnbobstones.watershipdown.org/lapine/overview.html">http://bitsnbobstones.watershipdown.org/lapine/overview.html</a></p>

<p class="bibliomixed"><a id="[Ignatchenko13]"></a>[Ignatchenko13] â€˜A Model for Debug Complexityâ€™, Sergey Ignatchenko and Dmytro Ivanchykhin, <em>Overload</em> 114, April 2013</p>

<p class="bibliomixed">[WikiAssertion] <a href="http://en.wikipedia.org/wiki/Assertion_(software_development)#Assertions_in_design_by_contract">http://en.wikipedia.org/wiki/Assertion_(software_development)#Assertions_in_design_by_contract</a>:<em>Assertions can function as a form of documentation: they can describe the state the code expects to find before it runs (its preconditions), and the state the code expects to result in when it is finished running (postconditions); they can also specify invariants of a class.</em></p>

<h2>Acknowledgement</h2>
<p>Cartoons by Sergey Gordeev from Gordeev Animation Graphics, Prague.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
