A place to cache linked articles (think custom and personal wayback machine)
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

1年前
1年前
1年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>The Illusion Of Developer “Productivity” Opens The Door To Snake Oil (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Is that even respected? Retrospectively? What a shAItshow…
  28. https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ -->
  29. <meta name="robots" content="noai, noimageai">
  30. <!-- Documented, feel free to shoot an email. -->
  31. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  32. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  36. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  37. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  38. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  39. <script>
  40. function toggleTheme(themeName) {
  41. document.documentElement.classList.toggle(
  42. 'forced-dark',
  43. themeName === 'dark'
  44. )
  45. document.documentElement.classList.toggle(
  46. 'forced-light',
  47. themeName === 'light'
  48. )
  49. }
  50. const selectedTheme = localStorage.getItem('theme')
  51. if (selectedTheme !== 'undefined') {
  52. toggleTheme(selectedTheme)
  53. }
  54. </script>
  55. <meta name="robots" content="noindex, nofollow">
  56. <meta content="origin-when-cross-origin" name="referrer">
  57. <!-- Canonical URL for SEO purposes -->
  58. <link rel="canonical" href="https://codemanship.wordpress.com/2023/09/25/the-illusion-of-developer-productivity-opens-the-door-to-snake-oil/">
  59. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  60. <article>
  61. <header>
  62. <h1>The Illusion Of Developer “Productivity” Opens The Door To Snake Oil</h1>
  63. </header>
  64. <nav>
  65. <p class="center">
  66. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  67. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  68. </svg> Accueil</a> •
  69. <a href="https://codemanship.wordpress.com/2023/09/25/the-illusion-of-developer-productivity-opens-the-door-to-snake-oil/" title="Lien vers le contenu original">Source originale</a>
  70. </p>
  71. </nav>
  72. <hr>
  73. <figure class="wp-block-image size-large"><a href="https://codemanship.files.wordpress.com/2023/09/a_footballer.png"><img data-attachment-id="1781" data-permalink="https://codemanship.wordpress.com/2023/09/25/the-illusion-of-developer-productivity-opens-the-door-to-snake-oil/a_footballer/" data-orig-file="https://codemanship.files.wordpress.com/2023/09/a_footballer.png" data-orig-size="1456,816" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="a_footballer" data-image-description="" data-image-caption="" data-medium-file="https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=300" data-large-file="https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=840" src="https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=1024" alt="" class="wp-image-1781" srcset="https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=1024 1024w, https://codemanship.files.wordpress.com/2023/09/a_footballer.png 1456w, https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=150 150w, https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=300 300w, https://codemanship.files.wordpress.com/2023/09/a_footballer.png?w=768 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px"></a><figcaption class="wp-element-caption">A footballer’s productivity is ultimately measured by how many goals the team scores</figcaption></figure>
  74. <p>There’s been much talk about measuring the productivity of software developers, triggered by a <a href="https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/yes-you-can-measure-software-developer-productivity">report from management consultants McKinsey </a>claiming to have succeeded where countless others over many decades have failed.</p>
  75. <p>I’m not going to dwell on the contents, as I prefer not to flatter it with that kind of scrutiny. Suffice to say, their ideas are naive at best. File in the usual place with your used egg shells and empty milk cartons.</p>
  76. <p>What McKinsey’s take suffers from is very, very common: they’ve mistaken activity for outcomes. Activity is easy to measure at an individual level, outcomes not so much. In fact, outcomes are often difficult to quantify at all.</p>
  77. <p>My first observation is that it’s not individual developers who produce outcomes; outcomes are achieved by the <em>team</em>. Just as there are players in a football team who usually don’t score goals, but without them fewer goals would be scored, there are usually people in a dev team who would be viewed as “unproductive” by McKinsey’s yardstick, but without whom the team as a whole would achieve much less. (See <a href="https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/yes-you-can-measure-software-developer-productivity">Dan North’s brilliant skewering of their metrics</a> using the very highly valuable Tim McKinnon – and I know, because I’ve worked with him – as the example.)</p>
  78. <p>My second observation is that outcomes in software development are rarely what they seem. Is our goal really to deliver code? Or is it to solve customers’ problems? Think of a doctor; is their goal to deliver treatments, or is to make us better?</p>
  79. <p>We in software, sadly, tend to be in the treatments business, not in the patients business. We’re Big Pharma. And in the same way that Big Pharma invests massively in persuading us that we have the illness their potion cures, we have a tendency to try to get the customer’s problem to fit our solution. And so it is that “productivity” tends to be about the potion, and not the patient.</p>
  80. <p>And so I wholeheartedly reject this individualist, mechanistic approach to measuring developer productivity. It’s nonsense. But I can understand why the <em>idea</em> appeals to managers in particular. The Illusion of Control<sup>TM</sup> has a strong pull in a situation where, in reality, managers have no real control beyond what to fund and what not to fund, and who to hire and who to fire. Who <em>wouldn’t </em>want those decisions to appear empirical and rational, and not the gambles they actually are?</p>
  81. <p>But more important to me is how this illusion can impact the very real business of solving customers’ problems with software. When all our focus is on potions and not patients, it’s easy for Snake Oil to creep in to the process.</p>
  82. <p>At time of writing, there’s much talk and incredible hype about one particular snake oil that promises much but, as far as I’ve managed to see with concrete examples that can be verified, delivers little to nothing for patients: Large Language Models.</p>
  83. <p>Code generation using LLMs like ChatGPT is, like all generative A.I., <em><a href="https://youtu.be/_nG6d6HSGB4?si=uqr4CehZBXOT6Hpy">impressive but wrong</a></em>. Having spent more than one hundred hours experimenting with GPT-4 and trying to replicate some of the claims people are making, I’ve seen how the illusion of productivity can suck us in. Yes, you <em>are</em> creating code faster. No, that code doesn’t work a lot of the time.</p>
  84. <p>But if we measure our productivity by “how far we kick the ball” instead of “how many goals the team scores”, that can seem like a Win. It falls into the same trap that thinking skimping on developer testing – or skipping it altogether – helps us deliver sooner. Deliver what, exactly? Bugs?</p>
  85. <p>On their website, GitHub claim that 88% of developers using <a href="https://github.com/features/copilot">Copilot</a> <em>feel</em> more productive. But what percentage of developers also <em>feel</em> that skipping some developer testing helps them deliver working software sooner. I could take a wild guess at somewhere in the ballpark of 88%, perhaps.</p>
  86. <p><a href="https://github.blog/2022-09-07-research-quantifying-github-copilots-impact-on-developer-productivity-and-happiness/">They did a study, of course</a>. (There’s always a study!) They tasked developers with writing a web server in JavaScript from scratch, some using Copilot, some doing it all by hand. And lo and behold, the developers who used Copilot completed that task in 55% less time. Isn’t it marvellous how vendor-funded studies always seem to back up their claims?</p>
  87. <p>But let’s look a little closer, shall we? First of all, since when were customer requirements like “Write me a web server”? A typical software system used in business, for example, will have complex rules that are usually not precisely defined up front, but rather discovered through customer feedback. And in that sense, how quickly we converge on a working solution will depend heavily on iterating, and on our ability to evolve the code. This wasn’t part of their exercise.</p>
  88. <p>Also, ahem.. If there was any problem that Copilot was probably already trained on, it’s <a href="https://github.com/search?q=http+server+language%3AJavaScript&amp;type=repositories&amp;l=JavaScript">JavaScript web servers</a>. People have noted how good GPT-4 is at solving online coding problems that were published before the training data cut-off date, but <a href="https://www.aisnakeoil.com/p/gpt-4-and-professional-benchmarks">not so hot at solving problems published after that</a>. I’d like to see how it performs on a novel problem. (In my own experiments with it, poorly.)</p>
  89. <p>And two more observations: </p>
  90. <p>First, this study focuses on developers working alone for a relatively short amount of time. Let’s see how it performs when a <em>team</em> is working on a more complex problem -each working on their own part of the system – for several days. That’s a lot of rapidly-changing context for an LLM. It’s easy to fool ourselves into believing something makes us better at running marathons because it helped us run the 100m dash faster. </p>
  91. <p>Secondly, GitHub’s musings on measuring developer productivity suffer a very similar “potions over patients” bias to the McKinsey report.</p>
  92. <p>And vendors have a very real incentive to want us to believe that the big problems in software development can be solved with their tools.</p>
  93. <p>Given the very high stakes for our industry – probably visible from space by now – I think it would be useful to see bigger, wider and more realistic studies of the impact of tools like Copilot on the capability of <em>teams</em> to <em>solve real customer problems</em>. As with almost every super-duper-we’ll-never-be-poor-or-hungry-again CASE tool revolution that’s come before, I suspect the answer will be “none at all”. But you can’t charge $19 a month for “none at all”. (Well, okay, you <em>can</em>. Just as long as there are enough people out there who focus on potions instead of patients.)</p>
  94. <p>But here’s the thing: I suspect bigger, wider, longer, more realistic studies of the impact on development <em>team</em> productivity might reveal simply that we still don’t know what that means.</p>
  95. </article>
  96. <hr>
  97. <footer>
  98. <p>
  99. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  100. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  101. </svg> Accueil</a> •
  102. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  103. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  104. </svg> Suivre</a> •
  105. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  106. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  107. </svg> Pro</a> •
  108. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  109. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  110. </svg> Email</a> •
  111. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  112. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  113. </svg> Légal</abbr>
  114. </p>
  115. <template id="theme-selector">
  116. <form>
  117. <fieldset>
  118. <legend><svg class="icon icon-brightness-contrast">
  119. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  120. </svg> Thème</legend>
  121. <label>
  122. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  123. </label>
  124. <label>
  125. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  126. </label>
  127. <label>
  128. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  129. </label>
  130. </fieldset>
  131. </form>
  132. </template>
  133. </footer>
  134. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  135. <script>
  136. function loadThemeForm(templateName) {
  137. const themeSelectorTemplate = document.querySelector(templateName)
  138. const form = themeSelectorTemplate.content.firstElementChild
  139. themeSelectorTemplate.replaceWith(form)
  140. form.addEventListener('change', (e) => {
  141. const chosenColorScheme = e.target.value
  142. localStorage.setItem('theme', chosenColorScheme)
  143. toggleTheme(chosenColorScheme)
  144. })
  145. const selectedTheme = localStorage.getItem('theme')
  146. if (selectedTheme && selectedTheme !== 'undefined') {
  147. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  148. }
  149. }
  150. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  151. window.addEventListener('load', () => {
  152. let hasDarkRules = false
  153. for (const styleSheet of Array.from(document.styleSheets)) {
  154. let mediaRules = []
  155. for (const cssRule of styleSheet.cssRules) {
  156. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  157. continue
  158. }
  159. // WARNING: Safari does not have/supports `conditionText`.
  160. if (cssRule.conditionText) {
  161. if (cssRule.conditionText !== prefersColorSchemeDark) {
  162. continue
  163. }
  164. } else {
  165. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  166. continue
  167. }
  168. }
  169. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  170. }
  171. // WARNING: do not try to insert a Rule to a styleSheet you are
  172. // currently iterating on, otherwise the browser will be stuck
  173. // in a infinite loop…
  174. for (const mediaRule of mediaRules) {
  175. styleSheet.insertRule(mediaRule.cssText)
  176. hasDarkRules = true
  177. }
  178. }
  179. if (hasDarkRules) {
  180. loadThemeForm('#theme-selector')
  181. }
  182. })
  183. </script>
  184. </body>
  185. </html>