Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <!doctype html>
  2. <html lang=fr>
  3. <head>
  4. <!-- Always define the charset before the title -->
  5. <meta charset=utf-8>
  6. <title>Benchmarks map, filter vs. list-comprehensions — 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/20061025-benchmarks-map-filter-vs-list-comprehensions">
  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">Benchmarks map, filter vs. list-comprehensions</h1>
  42. <article typeof="schema:BlogPosting">
  43. <div property="schema:articleBody">
  44. <img src="/static/david/biologeek/images/logos/seb_sauvage.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
  45. <p>Je viens de tomber sur les <a href="http://sebsauvage.net/python/snyppets/">snyppets de Seb Sauvage</a> (site que j'apprécie beaucoup par ailleurs) et il y a une phrase qui m'a interpellé sur le <a href="http://sebsauvage.net/python/snyppets/#zip_filter_map">paragraphe consacré à zip, map, filter et aux list-comprehensions</a>&nbsp;:</p>
  46. <blockquote><p>Except that {map|filter} is <strong>faster</strong>. (than list-comprehensions)</p></blockquote>
  47. <p>Ni une, ni deux, je récupère l'<a href="http://programmation-python.org/sections/blog/2006_10_05_article-sur-code">article de Tarek</a> qui est très bon et qui comporte une fonction testant la durée d'execution des fonctions pour pouvoir comparer. J'avais <a href="https://larlet.fr/david/biologeek/archives/20060121-bonnes-pratiques-de-la-programmation-en-python/">déjà essayé d'autres fonctions</a> mais autant innover un peu.</p>
  48. <p>Allons-y donc avec le décorateur suivant&nbsp;:</p>
  49. <pre>from test import pystone
  50. import time
  51. kPs = 1000
  52. TOLERANCE = 0.5 * kPs
  53. def mesure_pystone():
  54. pystone.pystones(loops=pystone.LOOPS)
  55. pystone.pystones(loops=pystone.LOOPS)
  56. return pystone.pystones(loops=pystone.LOOPS)
  57. def timedtest(function, local_pystones=mesure_pystone()):
  58. """ Decorator to measure execution time in pystones """
  59. def wrapper(*args, **kw):
  60. all = []
  61. for i in range(3):
  62. start_time = time.time()
  63. try:
  64. res = function(*args, **kw)
  65. finally:
  66. total_time = time.time() - start_time
  67. if total_time == 0:
  68. temps = 0
  69. else:
  70. ratio = local_pystones[0] / local_pystones[1]
  71. temps = total_time / ratio
  72. all.append(temps)
  73. print '%d pystones' % min(all)
  74. return res
  75. return wrapper</pre>
  76. <p>J'ai testé les fonctions suivantes qui ne sont pas les mêmes que les exemples de Seb mais qui retournent (elles, <a href="http://www.haypocalc.com/blog/">merci Haypo</a> :-)) le même résultat&nbsp;:</p>
  77. <pre>@timedtest
  78. def map_without_list_comprehension():
  79. for i in range(10000):
  80. map(abs, [-5,7,-12])
  81. @timedtest
  82. def map_with_list_comprehension():
  83. for i in range(10000):
  84. [abs(i) for i in [-5,7,-12]]
  85. print '=== map vs. list-comprehension ==='
  86. print 'map without list-comprehension:'
  87. map_without_list_comprehension()
  88. print 'map with list-comprehension:'
  89. map_with_list_comprehension()
  90. @timedtest
  91. def filter_without_list_comprehension():
  92. for i in range(10000):
  93. filter(abs, [-5,7,0,-12] )
  94. @timedtest
  95. def filter_with_list_comprehension():
  96. for i in range(10000):
  97. [i for i in [-5,7,0,-12] if i]
  98. print '=== filter vs. list-comprehension ==='
  99. print 'filter without list-comprehension:'
  100. filter_without_list_comprehension()
  101. print 'filter with list-comprehension:'
  102. filter_with_list_comprehension()</pre>
  103. <p>Et voila les résultats obtenus&nbsp;:</p>
  104. <blockquote><p>=== map vs. list-comprehension ===<br />
  105. map without list-comprehension:<br />
  106. 638 pystones<br />
  107. map with list-comprehension:<br />
  108. 534 pystones<br />
  109. === filter vs. list-comprehension ===<br />
  110. filter without list-comprehension:<br />
  111. 612 pystones<br />
  112. filter with list-comprehension:<br />
  113. 550 pystones<br /></p></blockquote>
  114. <p>Il me semble que c'est sans appel&nbsp;: les list-comprehensions sont <strong>toujours</strong> plus rapides que map ou filter avec Python 2.4. Il faudrait tester tout ça avec Python 2.5 mais je pense que les résultats seraient encore plus significatifs.</p>
  115. </div>
  116. </article>
  117. <footer>
  118. <h6 property="schema:datePublished">— 25/10/2006</h6>
  119. </footer>
  120. </section>
  121. <section>
  122. <div>
  123. <h3>Articles peut-être en rapport</h3>
  124. <ul>
  125. <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>
  126. <li><a href="/david/biologeek/archives/20060425-python-et-underscore/" title="Accès à Python : lisibilité vs simplicité">Python : lisibilité vs simplicité</a></li>
  127. <li><a href="/david/biologeek/archives/20060304-principales-nouveautes-dans-python-25/" title="Accès à Principales nouveautés dans Python 2.5">Principales nouveautés dans Python 2.5</a></li>
  128. </ul>
  129. </div>
  130. </section>
  131. <section>
  132. <div id="comments">
  133. <h3>Commentaires</h3>
  134. <div class="comment" typeof="schema:UserComments">
  135. <p class="comment-meta">
  136. <span class="comment-author" property="schema:creator">Tarek</span> le <span class="comment-date" property="schema:commentTime">26/10/2006</span> :
  137. </p>
  138. <div class="comment-content" property="schema:commentText">
  139. <p>Le même script sous Python 2.5 :<br />
  140. <br />
  141. tziade@dabox:~$ python test2.py<br />
  142. === map vs. list-comprehension ===<br />
  143. map without list-comprehension:<br />
  144. 707 pystones<br />
  145. map with list-comprehension:<br />
  146. 634 pystones<br />
  147. === filter vs. list-comprehension ===<br />
  148. filter without list-comprehension:<br />
  149. 687 pystones<br />
  150. filter with list-comprehension:<br />
  151. 634 pystones</p>
  152. </div>
  153. </div>
  154. <div class="comment" typeof="schema:UserComments">
  155. <p class="comment-meta">
  156. <span class="comment-author" property="schema:creator">JS</span> le <span class="comment-date" property="schema:commentTime">26/10/2006</span> :
  157. </p>
  158. <div class="comment-content" property="schema:commentText">
  159. <p>Bon, j'ai rien compris au map et list-comprehension, faudrait que je regarde ca de plus près...<br />
  160. <br />
  161. Par contre, t'es sur #python-fr ???</p>
  162. </div>
  163. </div>
  164. <div class="comment" typeof="schema:UserComments">
  165. <p class="comment-meta">
  166. <span class="comment-author" property="schema:creator">sebsauvage</span> le <span class="comment-date" property="schema:commentTime">01/12/2006</span> :
  167. </p>
  168. <div class="comment-content" property="schema:commentText">
  169. <p>Hello !<br />
  170. <br />
  171. Tu as oublié qu'avec de si petites données de test, l'overhead d'appel aux fonction devient non négligeable.<br />
  172. <br />
  173. J'ai refait les tests avec de plus grands ensembles de données et je maintien ce que j'ai dit:<br />
  174. map et filter sont plus rapide que list comprehension (sauf quand on combine map et filter).<br />
  175. <br />
  176. Voici le fichier de test:<br />
  177. <a href="http://sebsauvage.net/python/snyppets/maptest.py" title="http://sebsauvage.net/python/snyppets/maptest.py" rel="nofollow">sebsauvage.net/python/sny...</a><br />
  178. <br />
  179. Et les résultats:<br />
  180. ===== map_without_list_comprehension =====<br />
  181. 105 function calls in 0.231 CPU seconds<br />
  182. ===== map_with_list_comprehension =====<br />
  183. 1000005 function calls in 6.941 CPU seconds<br />
  184. <br />
  185. ===== filter_without_list_comprehension =====<br />
  186. 105 function calls in 0.074 CPU seconds<br />
  187. ===== filter_with_list_comprehension =====<br />
  188. 1000005 function calls in 6.889 CPU seconds<br />
  189. <br />
  190. C'est sans appel: map et filter sont nettement plus rapides.<br />
  191. (Dans notre exemple: d'un facteur x30 pour map, et d'un facteur x93 pour filter)<br />
  192. <br />
  193. <br />
  194. ...sauf quand on doit les combiner:<br />
  195. ===== mapfilter_without_list_comprehension =====<br />
  196. 2042605 function calls in 13.935 CPU seconds<br />
  197. ===== mapfilter_with_list_comprehension =====<br />
  198. 521205 function calls in 3.795 CPU seconds<br />
  199. <br />
  200. Là la list comprehension est plus rapide.<br />
  201. <br />
  202. <br />
  203. Donc je ne me suis pas trompé, mais c'est à mitiger. :-)<br />
  204. Il vaut mieux profiler le code.<br />
  205. </p>
  206. </div>
  207. </div>
  208. <div class="comment" typeof="schema:UserComments">
  209. <p class="comment-meta">
  210. <span class="comment-author" property="schema:creator">xfeeder</span> le <span class="comment-date" property="schema:commentTime">29/06/2010</span> :
  211. </p>
  212. <div class="comment-content" property="schema:commentText">
  213. <p>les list-comprehensions sont toujours plus rapides que map ou filter avec Python 2.4.</p>
  214. </div>
  215. </div>
  216. </div>
  217. </section>
  218. <footer>
  219. <nav>
  220. <p>
  221. <small>
  222. 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>
  223. </small>
  224. </p>
  225. </nav>
  226. </footer>
  227. </div>
  228. <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
  229. <script data-no-instant>InstantClick.init()</script>
  230. </body>
  231. </html>