Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.html 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <!doctype html>
  2. <html lang=fr>
  3. <head>
  4. <!-- Always define the charset before the title -->
  5. <meta charset=utf-8>
  6. <title>Optimisation des chaînes de caractères en Python : le retour ! — Biologeek — David Larlet</title>
  7. <!-- Define a viewport to mobile devices to use - telling the browser to assume that the page is as wide as the device (width=device-width) and setting the initial page zoom level to be 1 (initial-scale=1.0) -->
  8. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  9. <!-- Fake favicon, to avoid extra request to the server -->
  10. <link rel="icon" href="data:;base64,iVBORw0KGgo=">
  11. <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
  12. <link rel="manifest" href="/manifest.json">
  13. <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
  14. <noscript>
  15. <style type="text/css">
  16. /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
  17. body {
  18. font-family: 'EquityTextB', serif;
  19. }
  20. h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
  21. font-family: 'EquityCapsB', sans-serif;
  22. font-variant: normal;
  23. }
  24. </style>
  25. </noscript>
  26. <!-- Canonical URL for SEO purposes -->
  27. <link rel="canonical" href="https://larlet.fr/david/biologeek/archives/20060127-optimisation-des-chaines-de-caracteres-en-python-le-retour">
  28. </head>
  29. <body>
  30. <div>
  31. <header>
  32. <nav>
  33. <p>
  34. <small>
  35. Je suis <a href="/david/" title="Profil public">David Larlet</a>, <a href="/david/pro/" title="Activité professionnelle">artisan</a> du web qui vous <a href="/david/pro/accompagnement/" title="Activité d’accompagnement">accompagne</a><span class="more-infos"> dans l’acquisition de savoirs pour concevoir des <a href="/david/pro/produits-essentiels/" title="Qu’est-ce qu’un produit essentiel ?">produits essentiels</a></span>. <span class="more-more-infos">Discutons ensemble d’une <a href="/david/pro/devis/" title="En savoir plus">non-demande de devis</a>.</span> Je partage ici mes <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et <a href="/david/correspondances/2017/" title="Lettres hebdomadaires">correspondances</a>.
  36. </small>
  37. </p>
  38. </nav>
  39. </header>
  40. <section>
  41. <h1 property="schema:name">Optimisation des chaînes de caractères en Python : le retour !</h1>
  42. <article typeof="schema:BlogPosting">
  43. <div property="schema:articleBody">
  44. <img src="/static/david/biologeek/images/logos/bonnes_pratiques_python.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
  45. <p>Dans les <a href="https://larlet.fr/david/biologeek/archives/20060121-optimisation-des-chaines-de-caracteres-en-python/">épisodes précédents</a>, je m'étonnais de voir des concaténations de chaînes de caractères être plus rapide que des remplissages de listes. Depuis je cogite car il est indiqué un peu partout qu'il faut privillégier les listes. Et j'ai fini par trouver une réponse :-).</p>
  46. <p>Considérons la même chaîne de caractères&nbsp;:</p>
  47. <pre>strings = ["tagada"]*1000000 + ["tsouintsouin"]*1000000</pre>
  48. <p>Et la même fonction <strong>foo2()</strong>&nbsp;:</p>
  49. <pre>def foo2():
  50. string_final = []
  51. for string in strings:
  52. if not "tsouin" in string:
  53. string_final.append(string)
  54. return "".join(string_final)</pre>
  55. <p>Donc cette fonction met environ <strong>4,70 secondes</strong> à créer cette énorme chaîne de caractères. Ce que j'avais alors oublié de tester, ce sont les alias. En effet, les fonctions de type <strong>list.append</strong> sont réévaluées à chaque itération en python, ce qui fait perdre un temps fou, la preuve en chiffres&nbsp;:</p>
  56. <pre>def foo3():
  57. string_final = []
  58. app = string_final.append
  59. for string in strings:
  60. if not "tsouin" in string:
  61. app(string)
  62. return "".join(string_final)</pre>
  63. <p>Et là on tombe à <strong>3,50 secondes</strong>&nbsp;! Ainsi les listes peuvent être plus rapides que les concaténations de chaînes de caractères, encore faut-il pouvoir créer un alias...</p>
  64. <p>Bon et puisque j'y suis, une autre petite astuce d'optimisation&nbsp;: on peut lire dans les <a href="http://www.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/CodeOptimization">astuces d'optimisation de Zope</a> qu'il vaut mieux utiliser les méthodes du module string plutôt que des portions de listes. Bon dit comme ça on comprend pas trop de quoi je parle alors un petit exemple pour clarifier tout ça&nbsp;:</p>
  65. <pre>def foo4():
  66. string_final = ""
  67. for string in strings:
  68. if string[:5] == "tagad":
  69. string_final += string
  70. return string_final
  71. def foo5():
  72. string_final = ""
  73. for string in strings:
  74. if string.startswith("tagad"):
  75. string_final += string
  76. return string_final</pre>
  77. <p>La méthode <strong>foo4()</strong> s'exécute en <strong>7,2 secondes</strong> et <strong>foo5()</strong> en <strong>12 secondes</strong>... tiens c'est le contraire qui est obtenu ici, me serais-je trompé&nbsp;? Je revérifie et non j'ai bien ces temps là d'exécution, soit presque le double lorsque l'on utilise les méthodes du module string.</p>
  78. <p>Première conclusion&nbsp;: vérifiez toujours les astuces d'optimisation qu'on vous propose (ceci est valable pour celles-ci aussi) car elle peuvent évoluer selon les versions de Python ou du contexte par exemple.</p>
  79. <p>Seconde conclusion&nbsp;: les listes finalement c'est pas si mal pour traiter les chaînes de caractères :-).</p>
  80. <p>Je vous rappelle qu'un billet récapitule l'ensemble des <a href="https://larlet.fr/david/biologeek/archives/20060121-bonnes-pratiques-de-la-programmation-en-python/">bonnes pratiques et optimisations en Python</a>.</p>
  81. </div>
  82. </article>
  83. <footer>
  84. <h6 property="schema:datePublished">— 27/01/2006</h6>
  85. </footer>
  86. </section>
  87. <section>
  88. <div>
  89. <h3>Articles peut-être en rapport</h3>
  90. <ul>
  91. <li><a href="/david/biologeek/archives/20080511-bonnes-pratiques-et-astuces-python/" title="Accès à Bonnes pratiques et astuces Python">Bonnes pratiques et astuces Python</a></li>
  92. <li><a href="/david/biologeek/archives/20061025-benchmarks-map-filter-vs-list-comprehensions/" title="Accès à Benchmarks map, filter vs. list-comprehensions">Benchmarks map, filter vs. list-comprehensions</a></li>
  93. <li><a href="/david/biologeek/archives/20060425-python-et-underscore/" title="Accès à Python : lisibilité vs simplicité">Python : lisibilité vs simplicité</a></li>
  94. </ul>
  95. </div>
  96. </section>
  97. <section>
  98. <div id="comments">
  99. <h3>Commentaires</h3>
  100. <div class="comment" typeof="schema:UserComments">
  101. <p class="comment-meta">
  102. <span class="comment-author" property="schema:creator">Kagou</span> le <span class="comment-date" property="schema:commentTime">27/01/2006</span> :
  103. </p>
  104. <div class="comment-content" property="schema:commentText">
  105. <p>C'est le genre de truc qui me fait peur quand je me dis que je vais apprendre python (c'est aussi valable pour les autres ). On peut faire une opération de bien ?!trop?! de manières différentes, avec des implications conséquentes. Il me faut trouver le livre idéal qui m'apprenne et me sensibilise à ce genre de problème.</p>
  106. </div>
  107. </div>
  108. <div class="comment" typeof="schema:UserComments">
  109. <p class="comment-meta">
  110. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">27/01/2006</span> :
  111. </p>
  112. <div class="comment-content" property="schema:commentText">
  113. <p>Non justement en Python il y a très souvent une seule manière de bien faire les choses et c'est d'ailleurs la raison d'être de ces billets :)</p>
  114. </div>
  115. </div>
  116. <div class="comment" typeof="schema:UserComments">
  117. <p class="comment-meta">
  118. <span class="comment-author" property="schema:creator">Tarek</span> le <span class="comment-date" property="schema:commentTime">11/03/2006</span> :
  119. </p>
  120. <div class="comment-content" property="schema:commentText">
  121. <p>En fait entre Python 2.3 et Python 2.4 la gestion des chaînes a changée, rendant obsolètes et parfois même plus lentes des astuces qu'on trouve encore sur le web.<br />
  122. <br />
  123. Conclusion: il faut toujours indiquer la version de Python utilisée dans les astuces de ce genre. </p>
  124. </div>
  125. </div>
  126. <div class="comment" typeof="schema:UserComments">
  127. <p class="comment-meta">
  128. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">11/03/2006</span> :
  129. </p>
  130. <div class="comment-content" property="schema:commentText">
  131. <p>Oui, je l'ai appris en lisant un très bon livre, je suis d'ailleurs en train d'en écrire une critique ;)</p>
  132. </div>
  133. </div>
  134. <div class="comment" typeof="schema:UserComments">
  135. <p class="comment-meta">
  136. <span class="comment-author" property="schema:creator">soumia</span> le <span class="comment-date" property="schema:commentTime">19/05/2011</span> :
  137. </p>
  138. <div class="comment-content" property="schema:commentText">
  139. <p>slt, j&#39;ai besoin de trouver la solution de prb de décomposition de la chaine de caractéres en sous tranche pour la parcourir et récuperer ces tranches pour les utiliser dans un autre traitement (ces tranches sont séparer par des blancs), merci de m&#39;aider </p>
  140. </div>
  141. </div>
  142. </div>
  143. </section>
  144. <footer>
  145. <nav>
  146. <p>
  147. <small>
  148. Je réponds quasiment toujours aux <a href="m&#x61;ilto:d&#x61;vid%40l&#x61;rlet&#46;fr" title="Envoyer un email">emails</a> (<a href="/david/signature/" title="Ma signature actuelle avec possibilité de chiffrement">signés</a>) et vous pouvez me rencontrer à Montréal. <span class="more-infos">N’hésitez pas à <a href="/david/log/" title="Être tenu informé des mises à jour">vous abonner</a> pour être tenu informé des publications récentes.</span>
  149. </small>
  150. </p>
  151. </nav>
  152. </footer>
  153. </div>
  154. <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
  155. <script data-no-instant>InstantClick.init()</script>
  156. </body>
  157. </html>