A place to cache linked articles (think custom and personal wayback machine)
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="en">
  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>command center: Simplicity (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://commandcenter.blogspot.com/2023/12/simplicity.html">
  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>command center: Simplicity</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://commandcenter.blogspot.com/2023/12/simplicity.html" title="Lien vers le contenu original">Source originale</a>
  70. <br>
  71. Mis en cache le 2024-02-18
  72. </p>
  73. </nav>
  74. <hr>
  75. <p><span>In May 2009, Google hosted an internal "Design Wizardry" panel, with talks by Jeff Dean, </span><span>Mike Burrows, Paul Haahr, Alfred Spector, Bill Coughran, and myself.</span><span><span> Here is a lightly edited transcript of my talk. Some of the details have aged out, but the themes live on, now perhaps more than ever.</span></span></p>
  76. <p><span>---</span></p>
  77. <p class="p1"><span class="s1"><span><br></span></span></p>
  78. <p class="p1"><span class="s1"><span>Simplicity is better than complexity.</span></span></p>
  79. <p class="p2"><span><span class="s1"></span><br></span></p>
  80. <p class="p1"><span class="s1"><span>Simpler things are easier to understand, easier to build, easier to debug, and easier to maintain. Easier to understand is the most important, because it leads to the others. </span></span><span>Look at the web page for google.com. One text box. Type your query, get useful results. That's brilliantly simple design and a major reason for Google's success. Earlier search engines had much more complicated interfaces. Today they have either mimicked ours, or feel really hard to use.</span></p>
  81. <p class="p2"><span><span class="s1"></span><br></span></p>
  82. <p class="p1"><span class="s1"><span>That's google.com. But what about what's behind it? What about GWS? How you do you invoke it? I looked at the argument list of a running GWS (<a href="https://en.wikipedia.org/wiki/Google_Web_Server" target="_blank">Google Web Server</a>) instance. XX,XXX characters of configuration flags. XXX arguments. A few name backend machines. Some configure backends. Some enable or disable properties. Most of them are probably correct. I guarantee some of them are wrong or at least obsolete.</span></span></p>
  83. <p class="p2"><span><span class="s1"></span><br></span></p>
  84. <p class="p1"><span class="s1"><span>So, here's my question: How can the company that designed google.com be the same company that designed GWS? The answer is that GWS configuration structure was not really designed. It grew organically. Organic growth is not simple; it generates fantastic complexity. Each piece, each change may be simple, but put together the complexity becomes overwhelming.</span></span></p>
  85. <p class="p2"><span><span class="s1"></span><br></span></p>
  86. <p class="p1"><span class="s1"><span>Complexity is multiplicative. In a system, like Google, that is assembled from components, every time you make one part more complex, some of the added complexity is reflected in the other components. It's complexity runaway.</span></span></p>
  87. <p class="p2"><span><span class="s1"></span><br></span></p>
  88. <p class="p1"><span class="s1"><span>It's also endemic.</span></span></p>
  89. <p class="p2"><span><span class="s1"></span><br></span></p>
  90. <p class="p1"><span class="s1"><span>Many years ago, Tom Cargill took a year off from Bell Labs Research to work in development. He joined a group where every subsystem's code was printed in a separate binder and stored on a shelf in each office. Tom discovered that one of those subsystems was almost completely redundant; most of its services were implemented elsewhere. So he spent a few months making it completely redundant. He deleted 15,000 lines of code. When he was done, he removed an entire binder from everybody's shelf. He reduced the complexity of the system. Less code, less to test, less to maintain. His coworkers loved it.</span></span></p>
  91. <p class="p2"><span><span class="s1"></span><br></span></p>
  92. <p class="p1"><span class="s1"><span>But there was a catch. During his performance review, he learned that management had a metric for productivity: lines of code. Tom had negative productivity. In fact, because he was so successful, his entire group had negative productivity. He returned to Research with his tail between his legs.</span></span></p>
  93. <p class="p2"><span><span class="s1"></span><br></span></p>
  94. <p class="p1"><span class="s1"><span>And he learned his lesson: complexity is endemic. Simplicity is not rewarded.</span></span></p>
  95. <p class="p2"><span><span class="s1"></span><br></span></p>
  96. <p class="p1"><span class="s1"><span>You can laugh at that story. We don't do performance review based on lines of code.</span></span></p>
  97. <p class="p2"><span><span class="s1"></span><br></span></p>
  98. <p class="p1"><span class="s1"><span>But we're actually not far off. Who ever got promoted for deleting Google code? We revel in the code we have. It's huge and complex. New hires struggle to grasp it and we spend enormous resources training and mentoring them so they can cope. We pride ourselves in being able to understand it and in the freedom to change it.</span></span></p>
  99. <p class="p2"><span><span class="s1"></span><br></span></p>
  100. <p class="p1"><span class="s1"><span>Google is a democracy; the code is there for all to see, to modify, to improve, to add to. But every time you add something, you add complexity. Add a new library, you add complexity. Add a new storage wrapper, you add complexity. Add an option to a subsystem, you complicate the configuration. And when you complicate something central, such as a networking library, you complicate everything.</span></span></p>
  101. <p class="p2"><span><span class="s1"></span><br></span></p>
  102. <p class="p1"><span class="s1"><span>Complexity just happens and its costs are literally exponential.</span></span></p>
  103. <p class="p2"><span><span class="s1"></span><br></span></p>
  104. <p class="p1"><span class="s1"><span>On the other hand, simplicity takes work—but it's all up front. Simplicity is very hard to design, but it's easier to build and much easier to maintain. By avoiding complexity, simplicity's benefits are exponential.</span></span></p>
  105. <p class="p2"><span><span class="s1"></span><br></span></p>
  106. <p class="p1"><span class="s1"><span>Pardon the solipsism but look at the query logging system. It's far from perfect but it was designed to be—and still is—the only system at Google that solves the particular, central problem it was designed to solve. Because it is the only one, it guarantees stability, security, uniformity of use, and all the economies of scale. There is no way Google would be where it is today if every team rolled out its own logging infrastructure.</span></span></p>
  107. <p class="p2"><span><span class="s1"></span><br></span></p>
  108. <p class="p1"><span class="s1"><span>But the lesson didn't spread. Teams are constantly proposing new storage systems, new workflow managers, new libraries, new infrastructure.</span></span></p>
  109. <p class="p2"><span><span class="s1"></span><br></span></p>
  110. <p class="p1"><span class="s1"><span>All that duplication and proliferation is far too complex and it is killing us because the complexity is slowing us down.</span></span></p>
  111. <p class="p2"><span><span class="s1"></span><br></span></p>
  112. <p class="p1"><span class="s1"><span>We have a number of engineering principles at Google. Make code readable. Make things testable. Don't piss off the SREs. Make things fast.</span></span></p>
  113. <p class="p2"><span><span class="s1"></span><br></span></p>
  114. <p class="p1"><span class="s1"><span>Simplicity has never been on that list. But here's the thing: Simplicity is more important than any of them. Simpler designs are more readable. Simpler code is easier to test. Simpler systems are easier to explain to the SREs, and easier to fix when they fail.</span></span></p>
  115. <p class="p2"><span><span class="s1"></span><br></span></p>
  116. <p class="p1"><span class="s1"><span>Plus, simpler systems run faster.</span></span></p>
  117. <p class="p2"><span><span class="s1"></span><br></span></p>
  118. <p class="p1"><span class="s1"><span>Notice I said systems there, not code. Sometimes—not always—to make code fast you need to complicate it; that can be unavoidable. But complex systems are NEVER fast—they have more pieces and their interactions are too poorly understood to make them fast. Complexity generates inefficiency.</span></span></p>
  119. <p class="p2"><span><span class="s1"></span><br></span></p>
  120. <p class="p1"><span class="s1"><span>Simplicity is even more important than performance. Because of the multiplicative effects of complexity, getting 2% performance improvement by adding 2% complexity—or 1% or maybe even .1%—isn't worth it.</span></span></p>
  121. <p class="p2"><span><span class="s1"></span><br></span></p>
  122. <p class="p1"><span class="s1"><span>But hold on! What about our Utilization Code Red?</span></span></p>
  123. <p class="p2"><span><span class="s1"></span><br></span></p>
  124. <p class="p1"><span class="s1"><span>We don't have utilization problems because our systems are too slow. We have utilization problems because our systems are too complex. We don't understand how they perform, individually or together. We don't know how to characterize their interactions.</span></span></p>
  125. <p class="p2"><span><span class="s1"></span><br></span></p>
  126. <p class="p1"><span class="s1"><span>The app writers don't fully understand the infrastructure.</span></span></p>
  127. <p class="p2"><span><span class="s1"></span><br></span></p>
  128. <p class="p1"><span class="s1"><span>The infrastructure writers don't fully understand the networks.</span></span></p>
  129. <p class="p2"><span><span class="s1"></span><br></span></p>
  130. <p class="p1"><span class="s1"><span>Or the apps for that matter. And so on and so on.</span></span></p>
  131. <p class="p2"><span><span class="s1"></span><br></span></p>
  132. <p class="p1"><span class="s1"><span>To compensate, everyone overprovisions and adds zillions of configuration options and adjustments. That makes everything even harder to understand.</span></span></p>
  133. <p class="p2"><span><span class="s1"></span><br></span></p>
  134. <p class="p1"><span class="s1"><span>Products manage to launch only by building walls around their products to isolate them from the complexity—which just adds more complexity.</span></span></p>
  135. <p class="p2"><span><span class="s1"></span><br></span></p>
  136. <p class="p1"><span class="s1"><span>It's a vicious cycle.</span></span></p>
  137. <p class="p2"><span><span class="s1"></span><br></span></p>
  138. <p class="p1"><span class="s1"><span>So think hard about what you're working on. Can it be simpler? Do you really need that feature? Can you make something better by simplifying, deleting, combining, or sharing? Sit down with the groups you depend on and understand how you can combine forces with them to design a simpler, shared architecture that doesn't involve defending against each other.</span></span></p>
  139. <p class="p2"><span><span class="s1"></span><br></span></p>
  140. <p class="p1"><span class="s1"><span>Learn about the systems that already exist, and build on them rather than around them. If an existing system doesn't do what you want, maybe the problem is in the design of your system, not that one.</span></span></p>
  141. <p class="p2"><span><span class="s1"></span><br></span></p>
  142. <p class="p1"><span class="s1"><span>If you do build a new component, make sure it's of general utility. Don't build infrastructure that solves only the problems of your own team.</span></span></p>
  143. <p class="p2"><span><span class="s1"></span><br></span></p>
  144. <p class="p1"><span class="s1"><span>It's easy to build complexity. In the rush to launch, it's quicker and easier to code than to redesign. But the costs accumulate and you lose in the long run.</span></span></p>
  145. <p class="p2"><span><span class="s1"></span><br></span></p>
  146. <p class="p1"><span class="s1"><span>The code repository contains 50% more lines of code than it did a year ago. Where will we be in another year? In 5 years?</span></span></p>
  147. <p class="p2"><span><span class="s1"></span><br></span></p>
  148. <p class="p1"><span class="s1"><span>If we don't bring the complexity under control, one day it won't be a Utilization Code Red. Things will get so complex, so slow, they'll just grind to a halt. That's called a Code Black.</span></span></p>
  149. </article>
  150. <hr>
  151. <footer>
  152. <p>
  153. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  154. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  155. </svg> Accueil</a> •
  156. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  157. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  158. </svg> Suivre</a> •
  159. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  160. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  161. </svg> Pro</a> •
  162. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  163. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  164. </svg> Email</a> •
  165. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  166. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  167. </svg> Légal</abbr>
  168. </p>
  169. <template id="theme-selector">
  170. <form>
  171. <fieldset>
  172. <legend><svg class="icon icon-brightness-contrast">
  173. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  174. </svg> Thème</legend>
  175. <label>
  176. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  177. </label>
  178. <label>
  179. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  180. </label>
  181. <label>
  182. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  183. </label>
  184. </fieldset>
  185. </form>
  186. </template>
  187. </footer>
  188. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  189. <script>
  190. function loadThemeForm(templateName) {
  191. const themeSelectorTemplate = document.querySelector(templateName)
  192. const form = themeSelectorTemplate.content.firstElementChild
  193. themeSelectorTemplate.replaceWith(form)
  194. form.addEventListener('change', (e) => {
  195. const chosenColorScheme = e.target.value
  196. localStorage.setItem('theme', chosenColorScheme)
  197. toggleTheme(chosenColorScheme)
  198. })
  199. const selectedTheme = localStorage.getItem('theme')
  200. if (selectedTheme && selectedTheme !== 'undefined') {
  201. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  202. }
  203. }
  204. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  205. window.addEventListener('load', () => {
  206. let hasDarkRules = false
  207. for (const styleSheet of Array.from(document.styleSheets)) {
  208. let mediaRules = []
  209. for (const cssRule of styleSheet.cssRules) {
  210. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  211. continue
  212. }
  213. // WARNING: Safari does not have/supports `conditionText`.
  214. if (cssRule.conditionText) {
  215. if (cssRule.conditionText !== prefersColorSchemeDark) {
  216. continue
  217. }
  218. } else {
  219. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  220. continue
  221. }
  222. }
  223. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  224. }
  225. // WARNING: do not try to insert a Rule to a styleSheet you are
  226. // currently iterating on, otherwise the browser will be stuck
  227. // in a infinite loop…
  228. for (const mediaRule of mediaRules) {
  229. styleSheet.insertRule(mediaRule.cssText)
  230. hasDarkRules = true
  231. }
  232. }
  233. if (hasDarkRules) {
  234. loadThemeForm('#theme-selector')
  235. }
  236. })
  237. </script>
  238. </body>
  239. </html>