<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python on Peter McConnell :: Réflexions d&#39;un ingénieur système Linux</title>
    <link>https://www.petermcconnell.com/fr/tags/python/</link>
    <description>Recent content in Python on Peter McConnell :: Réflexions d&#39;un ingénieur système Linux</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>fr</language>
    <copyright>&amp;copy; Peter McConnell 2023</copyright>
    <lastBuildDate>Mon, 26 Dec 2022 22:54:29 +0000</lastBuildDate><atom:link href="https://www.petermcconnell.com/fr/tags/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Ingénierie des performances avec Python 3.12</title>
      <link>https://www.petermcconnell.com/fr/posts/perf_eng_with_py12/</link>
      <pubDate>Mon, 26 Dec 2022 22:54:29 +0000</pubDate>
      
      <guid>https://www.petermcconnell.com/fr/posts/perf_eng_with_py12/</guid>
      <description>3.12 apporte le profilage des performances ! Prenez une seconde pour aller consulter https://docs.python.org/3.12/howto/perf_profiling.html et en effet le changelog à https://www.python.org/downloads/release/python-3120a3/
La partie importante (pour ce post) des liens ci-dessus est :
&amp;quot;&amp;quot;&amp;quot; Le profileur de performances Linux est un outil très puissant qui vous permet de profiler et d&amp;rsquo;obtenir des informations sur les performances de votre application. perf dispose également d&amp;rsquo;un écosystème d&amp;rsquo;outils très dynamique qui facilite l&amp;rsquo;analyse des données qu&amp;rsquo;il produit.</description>
      <content>&lt;p&gt;3.12 apporte le profilage des performances ! Prenez une seconde pour aller consulter &lt;a href=&#34;https://docs.python.org/3.12/howto/perf_profiling.html&#34;&gt;https://docs.python.org/3.12/howto/perf_profiling.html&lt;/a&gt; et en effet le changelog à &lt;a href=&#34;https://www.python.org/downloads/release/python-3120a3/&#34;&gt;https://www.python.org/downloads/release/python-3120a3/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La partie importante (pour ce post) des liens ci-dessus est :&lt;/p&gt;
&lt;p&gt;&amp;quot;&amp;quot;&amp;quot;
Le profileur de performances Linux est un outil très puissant qui vous permet de profiler et d&amp;rsquo;obtenir des informations sur les performances de votre application. perf dispose également d&amp;rsquo;un écosystème d&amp;rsquo;outils très dynamique qui facilite l&amp;rsquo;analyse des données qu&amp;rsquo;il produit.&lt;/p&gt;
&lt;p&gt;Le principal problème avec l&amp;rsquo;utilisation du profileur perf avec les applications Python est que perf ne permet d&amp;rsquo;obtenir des informations que sur les symboles natifs, c&amp;rsquo;est-à-dire les noms des fonctions et des procédures écrites en C. Cela signifie que les noms et les noms de fichiers des fonctions Python dans votre code n&amp;rsquo;apparaîtra pas dans la sortie de la perf.&lt;/p&gt;
&lt;p&gt;Depuis Python 3.12, l&amp;rsquo;interpréteur peut s&amp;rsquo;exécuter dans un mode spécial qui permet aux fonctions Python d&amp;rsquo;apparaître dans la sortie du profileur de performances. Lorsque ce mode est activé, l&amp;rsquo;interpréteur interposera un petit morceau de code compilé à la volée avant l&amp;rsquo;exécution de chaque fonction Python et il apprendra à perf la relation entre ce morceau de code et la fonction Python associée à l&amp;rsquo;aide de fichiers de mappage de perf.
&amp;quot;&amp;quot;&amp;quot;&lt;/p&gt;
&lt;h2 id=&#34;écrire-un-mauvais-programme&#34;&gt;écrire un &amp;ldquo;mauvais&amp;rdquo; programme&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai hâte d&amp;rsquo;essayer ça, alors allons-y. Tout d&amp;rsquo;abord, créons un script python à profiler. Je le fais avant d&amp;rsquo;installer Python 3.12 car je veux créer un FlameGraph de l&amp;rsquo;apparence de ce processus dans 3.10 vers 3.12. Ici, nous avons un script qui tente d&amp;rsquo;effectuer des recherches sur une grande liste :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run_dummy&lt;/span&gt;(numbers):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; findme &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; findme &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; numbers:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;trouvé&amp;#34;&lt;/span&gt;, trouvemoi)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;manqué&amp;#34;&lt;/span&gt;, me trouver)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; __name__ &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# create a large sized input to show off inefficiency&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    numbers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [i &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;20000000&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    start_time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()  &lt;span style=&#34;color:#75715e&#34;&gt;# get the current time [start]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    run_dummy(numbers)  &lt;span style=&#34;color:#75715e&#34;&gt;# run our inefficient method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    end_time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()  &lt;span style=&#34;color:#75715e&#34;&gt;# get the current time [end]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    duration &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; end_time &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; start_time  &lt;span style=&#34;color:#75715e&#34;&gt;# calculate the duration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Durée: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;duration&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; secondes&amp;#34;&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# print the duration&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En exécutant ceci, j&amp;rsquo;obtiens le résultat suivant:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3.10 assets/dummy/perf_py_proj/before.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99992&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99993&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99994&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99995&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99996&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99997&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99998&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Durée : 36.06884431838989 secondes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;36 secondes suffisent pour que nous prélevions un nombre raisonnable d&amp;rsquo;échantillons.&lt;/p&gt;
&lt;h2 id=&#34;des-flamegraphes&#34;&gt;des flamegraphes !&lt;/h2&gt;
&lt;p&gt;Nous pouvons maintenant créer notre &lt;a href=&#34;https://github.com/brendangregg/FlameGraph&#34;&gt;FlameGraph&lt;/a&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# enregistrer le profil dans le fichier &amp;#34;perf.data&amp;#34; (sortie par défaut)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf record -F &lt;span style=&#34;color:#ae81ff&#34;&gt;99&lt;/span&gt; -g -- python3.10 assets/dummy/perf_py_proj/before.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# lire perf.data (créé ci-dessus) et afficher la sortie de trace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf script &amp;gt; out.perf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# plier les échantillons de pile en une seule ligne&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ici, je fais référence à ~/FlameGraph/ - vous pouvez l&amp;#39;obtenir à partir de https://github.com/brendangregg/FlameGraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/stackcollapse-perf.pl out.perf &amp;gt; out.folded
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# générer un flamegraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/flamegraph.pl out.folded &amp;gt; ./assets/perf_example_python3.10.svg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cela nous donne un joli SVG qui visualise les traces :&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;python 3.10 perf flamegraph&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_example_python3.10.svg&#34; title=&#34;python 3.10 perf flamegraph&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ce n&amp;rsquo;est pas utile &amp;hellip; Je peux voir que la plupart du temps a été passé dans &amp;ldquo;new_keys_object.lto_priv.0&amp;rdquo; mais cela n&amp;rsquo;a aucun sens dans le contexte du code.&lt;/p&gt;
&lt;h2 id=&#34;cest-lheure-de-python-312&#34;&gt;C&amp;rsquo;est l&amp;rsquo;heure de Python 3.12&amp;hellip;&lt;/h2&gt;
&lt;p&gt;Je dois d&amp;rsquo;abord l&amp;rsquo;installer - les étapes pour cela varient selon le système d&amp;rsquo;exploitation - suivez les instructions de construction ici pour votre environnement : &lt;a href=&#34;https://github.com/python/cpython/tree/v3.12.0a3#build-instructions&#34;&gt;https://github.com/python/cpython/tree/v3.12.0a3#build-instructions&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pour moi sur ubuntu:22.04&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# assurez-vous que python3-dbg est installé&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get install python3-dbg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# construire python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export CFLAGS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./configure --enable-optimizations
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make test
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unset CFLAGS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# après cela, j&amp;#39;ai réinitialisé le lien symbolique de mon système python3 à 3.10 car 3.12 n&amp;#39;est pas encore stable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pour tester python3.12, j&amp;#39;appellerai &amp;#34;python3.12&amp;#34; au lieu de &amp;#34;python3&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ln -sf /usr/local/bin/python3.10 /usr/local/bin/python3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Avec cela installé, je dois d&amp;rsquo;abord activer le support des performances. Ceci est détaillé dans &lt;a href=&#34;https://docs.python.org/3.12/howto/perf_profiling.html&#34;&gt;https://docs.python.org/3.12/howto/perf_profiling.html&lt;/a&gt; et il y a trois options : 1) une variable d&amp;rsquo;environnement, 2) une option -X ou 3) dynamiquement en utilisant &lt;code&gt;sys&lt;/code&gt;. J&amp;rsquo;opterai pour l&amp;rsquo;approche des variables d&amp;rsquo;environnement car cela ne me dérange pas que &lt;em&gt;tout&lt;/em&gt; soit profilé pour un petit script :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export PYTHONPERFSUPPORT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Maintenant, nous répétons simplement le processus ci-dessus en utilisant à la place le binaire &lt;code&gt;python3.12&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# enregistrer le profil dans le fichier &amp;#34;perf.data&amp;#34; (sortie par défaut)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf record -F &lt;span style=&#34;color:#ae81ff&#34;&gt;99&lt;/span&gt; -g -- python3.12 assets/dummy/perf_py_proj/before.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# lire perf.data (créé ci-dessus) et afficher la sortie de trace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf script &amp;gt; out.perf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# plier les échantillons de pile en une seule ligne&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ici, je fais référence à ~/FlameGraph/ - vous pouvez l&amp;#39;obtenir à partir de https://github.com/brendangregg/FlameGraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/stackcollapse-perf.pl out.perf &amp;gt; out.folded
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# générer un flamegraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/flamegraph.pl out.folded &amp;gt; ./assets/perf_example_python3.12.before.svg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous allons d&amp;rsquo;abord jeter un coup d&amp;rsquo;œil au rapport avec &lt;code&gt;perf report -g -i perf.data&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;sortie du rapport de performance python 3.12&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_report.png&#34; title=&#34;rapport de performance python 3.12&#34;&gt;&lt;/p&gt;
&lt;p&gt;Impressionnant! Nous pouvons voir nos noms de fonctions Python et nos noms de scripts !&lt;/p&gt;
&lt;p&gt;Nous pouvons maintenant jeter un œil au SVG mis à jour qui visualise les traces avec Python 3.12 :&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;python 3.12 perf flamegraph&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_example_python3.12.before.svg&#34; title=&#34;python 3.12 perf flamegraph&#34;&gt;&lt;/p&gt;
&lt;p&gt;Cela semble déjà beaucoup plus utile. Nous voyons que la majorité du temps est consacrée à faire des comparaisons et dans la méthode list_contains. Nous pouvons également voir le fichier spécifique &lt;code&gt;before.py&lt;/code&gt; et la méthode &lt;code&gt;run_dummy&lt;/code&gt; qui l&amp;rsquo;appelle.&lt;/p&gt;
&lt;h2 id=&#34;temps-denquête--le-correctif&#34;&gt;Temps d&amp;rsquo;enquête / le correctif&lt;/h2&gt;
&lt;p&gt;Maintenant que nous savons où se trouve le problème dans notre code, nous pouvons jeter un œil au code source dans CPython pour voir pourquoi la méthode &lt;code&gt;list_contains&lt;/code&gt; serait si lente : &lt;a href=&#34;https://github.com/python/cpython/blob/&#34;&gt;https://github.com/python/cpython/blob/&lt;/a&gt; 199507b81a302ea19f93593965b1e5088195a6c5/Objects/listobject.c#L440&lt;/p&gt;
&lt;p&gt;&lt;em&gt;note : vous n&amp;rsquo;aurez peut-être pas toujours accès au code source - dans de telles circonstances, vous pouvez voir le désassemblage directement dans le rapport de performance pour avoir une idée de ce qui se passe. Je vais ajouter une section rapide à la fin montrant à quoi cela ressemble&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// J&amp;#39;ai trouvé ceci en allant sur https://github.com/python/cpython/ et en recherchant &amp;#34;list_contains&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;list_contains&lt;/span&gt;(PyListObject &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;a, PyObject &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;el)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    PyObject &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;item;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Py_ssize_t i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; cmp;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, cmp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; ; cmp &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Py_SIZE&lt;/span&gt;(a); &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        item &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;PyList_GET_ITEM&lt;/span&gt;(a, i);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;Py_INCREF&lt;/span&gt;(item);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cmp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;PyObject_RichCompareBool&lt;/span&gt;(item, el, Py_EQ);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;Py_DECREF&lt;/span&gt;(item);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; cmp;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nasty &amp;hellip; en regardant ce code, je peux voir que chaque fois qu&amp;rsquo;il est invoqué, il parcourt le tableau et effectue une comparaison avec chaque élément. C&amp;rsquo;est loin d&amp;rsquo;être idéal pour notre cas d&amp;rsquo;utilisation, alors revenons au code Python que nous avons écrit. Notre Flamegraph nous montre que le problème est dans notre méthode &lt;code&gt;run_dummy&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run_dummy&lt;/span&gt;(nombres):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; findme &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; findme &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; numbers: &lt;span style=&#34;color:#75715e&#34;&gt;# &amp;lt;- c&amp;#39;est ce qui déclenche list_contains&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;trouvé&amp;#34;&lt;/span&gt;, trouvemoi)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        autre:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;manqué&amp;#34;&lt;/span&gt;, me trouver)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous ne pouvons pas vraiment changer cette ligne car elle fait ce que nous voulons qu&amp;rsquo;elle fasse - identifier si un entier est dans &lt;code&gt;numbers&lt;/code&gt;. Peut-être pouvons-nous changer le type de données &amp;ldquo;numbers&amp;rdquo; pour un type mieux adapté aux recherches. Dans notre code existant, nous avons :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    numbers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [i &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;20000000&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    start_time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()  &lt;span style=&#34;color:#75715e&#34;&gt;# get the current time [start]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    run_dummy(numbers)  &lt;span style=&#34;color:#75715e&#34;&gt;# run our inefficient method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ici, nous avons utilisé un type de données LIST pour nos &amp;ldquo;nombres&amp;rdquo;, qui sous le capot (dans CPython) est implémenté sous forme de tableaux de taille dynamique et, en tant que tel, est loin d&amp;rsquo;être aussi efficace (O (N)) que les goûts d&amp;rsquo;un Hashtable pour regarder un élément (qui est O (1)). Un SET d&amp;rsquo;autre part (un autre type de données Python) est implémenté en tant que table de hachage et nous donnerait la recherche rapide que nous recherchons. Modifions le type de données dans notre code Python et voyons quel en est l&amp;rsquo;impact :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#75715e&#34;&gt;# nous allons juste changer cette ligne, en jetant des nombres dans un ensemble avant d&amp;#39;exécuter run_dummy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     run_dummy(set(numbers)) &lt;span style=&#34;color:#75715e&#34;&gt;# passage d&amp;#39;un set() pour des recherches rapides&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous pouvons maintenant répéter les étapes ci-dessus pour générer notre nouveau flamegraph :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# enregistrer le profil dans le fichier &amp;#34;perf.data&amp;#34; (sortie par défaut)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;enregistrement de performances -F &lt;span style=&#34;color:#ae81ff&#34;&gt;99&lt;/span&gt; -g -- python3.12 assets/dummy/perf_py_proj/after.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99998&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trouvé &lt;span style=&#34;color:#ae81ff&#34;&gt;99999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Durée : 0.8350753784179688 secondes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; perf record: Woken up &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; times to write data &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; perf record: Captured and wrote 0.039 MB perf.data &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;134&lt;/span&gt; samples&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous pouvons déjà voir que les choses se sont massivement améliorées. Là où auparavant cela prenait 36 secondes pour s&amp;rsquo;exécuter, cela prend maintenant 0,8 seconde ! Continuons à créer notre flamegraph pour le nouveau code amélioré :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# lire perf.data (créé ci-dessus) et afficher la sortie de trace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf script &amp;gt; out.perf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# plier les échantillons de pile en une seule ligne&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ici, je fais référence à ~/FlameGraph/ - vous pouvez l&amp;#39;obtenir à partir de https://github.com/brendangregg/FlameGraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/stackcollapse-perf.pl out.perf &amp;gt; out.folded
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# générer un flamegraph&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/FlameGraph/flamegraph.pl out.folded &amp;gt; ./assets/perf_example_python3.12.after.svg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;![python 3.12 parf flamegraph amélioré] (&lt;a href=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_example_python3.12.after.svg&#34;&gt;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_example_python3.12.after.svg&lt;/a&gt; &amp;ldquo;python 3.12 perf flamegraph amélioré&amp;rdquo;)&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agit d&amp;rsquo;un Flamegraph beaucoup plus sain et notre application est maintenant beaucoup plus rapide en conséquence. La prise en charge du profilage des performances dans Python 3.12 apporte un outil extrêmement utile aux ingénieurs logiciels qui souhaitent fournir des programmes rapides et je suis ravi de voir l&amp;rsquo;impact que cela aura sur le langage.&lt;/p&gt;
&lt;p&gt;bonus round : que faire quand on ne peut pas accéder au code source ?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Parfois, vous n&amp;rsquo;avez pas accès au code sous-jacent, ce qui peut rendre la compréhension de ce qui se passe beaucoup plus difficile. Heureusement, &lt;code&gt;perf report&lt;/code&gt; nous permet de visualiser le code désassemblé, ce qui peut aider à brosser un tableau de ce que fait réellement la machine. C&amp;rsquo;est un premier endroit raisonnable à regarder - j&amp;rsquo;ai tendance à préférer le code source si je peux m&amp;rsquo;en procurer car cela me permet de &amp;ldquo;blâmer&amp;rdquo; / de voir les commits et PR associés. Pour l&amp;rsquo;afficher, vous pouvez procéder comme suit :&lt;/p&gt;
&lt;p&gt;Ouvrez le rapport de perf et sélectionnez la ligne qui nous intéresse :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# cela suppose que nous avons déjà exécuté &amp;#39;perf record&amp;#39; pour générer perf.data ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perf report -g -i perf.data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img alt=&#34;perf report dissassembly&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_report_dis.1.png&#34; title=&#34;perf report dissassembly&#34;&gt;&lt;/p&gt;
&lt;p&gt;Appuyez sur Entrée et choisissez l&amp;rsquo;option d&amp;rsquo;annotation :&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Désassemblage du rapport de performances&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_report_dis.2.png&#34; title=&#34;Désassemblage du rapport de performances&#34;&gt;&lt;/p&gt;
&lt;p&gt;Voir! Ici, nous pouvons voir à la fois le code C et les instructions de la machine. Super utile ! Vous pouvez comparer la capture d&amp;rsquo;écran ci-dessous avec l&amp;rsquo;extrait de code qui nous intéresse : &lt;a href=&#34;https://github.com/python/cpython/blob/199507b81a302ea19f93593965b1e5088195a6c5/Objects/listobject.c#L440&#34;&gt;https://github.com/python/cpython/blob/199507b81a302ea19f93593965b1e5088195a6c5/Objects/listobject.c#L440&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;perf report dissassembly&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/petermcconnell.com/master/assets/perf_report_dis.3.png&#34; title=&#34;perf report dissassembly&#34;&gt;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>chatGPT - création d&#39;un outil de test de base de données automatisé</title>
      <link>https://www.petermcconnell.com/fr/posts/ai_db_testing/</link>
      <pubDate>Thu, 08 Dec 2022 11:41:50 +0000</pubDate>
      
      <guid>https://www.petermcconnell.com/fr/posts/ai_db_testing/</guid>
      <description>Création d&amp;rsquo;un outil de test de base de données automatisé avec ChatGPT
Hier soir, j&amp;rsquo;ai pensé essayer de faire en sorte que ChatGPT crée une base de données automatisée outil de test et les résultats étaient assez prometteurs.
En conclusion, avec des conseils, il a pu construire un projet à partir de zéro qui a exécuté un script python et une base de données postgres. Il a généré un schéma aléatoire et valeurs pour les tables générées aléatoirement.</description>
      <content>&lt;p&gt;Création d&amp;rsquo;un outil de test de base de données automatisé avec ChatGPT&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Hier soir, j&amp;rsquo;ai pensé essayer de faire en sorte que ChatGPT crée une base de données automatisée
outil de test et les résultats étaient assez prometteurs.&lt;/p&gt;
&lt;p&gt;En conclusion, avec des conseils, il a pu construire un projet à partir de zéro
qui a exécuté un script python et une base de données postgres. Il a généré un
schéma aléatoire et valeurs pour les tables générées aléatoirement. Il a fourni
un script Python qui inspecterait la base de données et exécuterait des requêtes
sur celle-ci.&lt;/p&gt;
&lt;p&gt;Est-ce que tout a fonctionné hors de la boîte? Non. Il y a quelques bogues à
corriger dans le python script qu&amp;rsquo;il a généré. Cependant, l&amp;rsquo;effort pour y
remédier n&amp;rsquo;est pas élevé et certainement l&amp;rsquo;ensemble du processus de bout en
bout est moins cher, en termes de temps, par rapport à partir de zéro.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai trouvé que les bogues rencontrés étaient en grande partie dus à mon manque
de clarté ou ordre des questions qui lui sont posées. Il était tout à fait
capable de réparer lui-même erreurs / mise à jour du code existant pour
correspondre aux nouvelles exigences lorsque demandé de le faire.&lt;/p&gt;
&lt;p&gt;Le seul problème &lt;em&gt;réel&lt;/em&gt; que j&amp;rsquo;ai rencontré était des erreurs d&amp;rsquo;API générales
que l&amp;rsquo;on pourrait attendez-vous à quelque chose d&amp;rsquo;aussi populaire dans un état
de prévisualisation précoce.&lt;/p&gt;
&lt;p&gt;Je suis sorti de cette expérience en voyant ChatGPT et tout ce qui suit comme
un aide au développement vraiment utile pour ceux qui savent déjà programmer.
Il m&amp;rsquo;a aidé à construire un outil plus rapidement que je n&amp;rsquo;aurais pu si je me
suis assis pour le faire à partir de gratter. Je ne le considère pas encore
comme un remplacement pour les ingénieurs en logiciel pour deux raisons
principales - premièrement : pour les applications non triviales, je soupçonne
la personne l&amp;rsquo;alimentation des exigences dans le système (ou &amp;ldquo;ingénieur
rapide&amp;rdquo;) doit avoir un idée raisonnable de la façon de construire un logiciel
en premier lieu, afin de savoir comment pour formuler des demandes et corriger
les erreurs / combler les lacunes. deuxièmement : le code étant généré n&amp;rsquo;est
pas toujours solide - sans qu&amp;rsquo;un ingénieur expérimenté examine et prendre
possession de tout code produit (la propriété étant importante pour raisons de
maintenance) alors il y a peu de garantie que vous obtiendrez ce que vous
espèrent.&lt;/p&gt;
&lt;p&gt;Cependant; c&amp;rsquo;est encore très tôt. Les problèmes décrits peuvent-ils être
résolus plus loin? Absolument. Ce type d&amp;rsquo;outillage sera-t-il &amp;ldquo;mauvais&amp;rdquo; pour les
logiciels l&amp;rsquo;ingénierie dans son ensemble, à long terme ? Peut-être.
Personnellement, je suis très heureux d&amp;rsquo;avoir cet outil dans mon arsenal - il
m&amp;rsquo;a déjà permis d&amp;rsquo;échafauder un prototype candidatures rapidement. Est-ce que
je l&amp;rsquo;utiliserais pour du code de production sur un lieu de travail ? Non plus
ou moins que je ne le ferais avec des extraits de stackoverflow ou de son
acabit. Pour le moment&lt;/p&gt;
&lt;p&gt;Github repository: &lt;a href=&#34;https://github.com/peter-mcconnell/gpt_sql_test_generator&#34;&gt;https://github.com/peter-mcconnell/gpt_sql_test_generator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Screenshots:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;step 2&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/2.png&#34; title=&#34;step 2&#34;&gt;
&lt;img alt=&#34;step 3&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/3.png&#34; title=&#34;step 3&#34;&gt;
&lt;img alt=&#34;step 4&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/4.png&#34; title=&#34;step 4&#34;&gt;
&lt;img alt=&#34;step 5&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/5.png&#34; title=&#34;step 5&#34;&gt;
&lt;img alt=&#34;step 6&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/6.png&#34; title=&#34;step 6&#34;&gt;
&lt;img alt=&#34;step 7&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/7.png&#34; title=&#34;step 7&#34;&gt;
&lt;img alt=&#34;step 8&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/8.png&#34; title=&#34;step 8&#34;&gt;
&lt;img alt=&#34;step 9&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/9.png&#34; title=&#34;step 9&#34;&gt;
&lt;img alt=&#34;step 10&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/10.png&#34; title=&#34;step 10&#34;&gt;
&lt;img alt=&#34;step 11&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/11.png&#34; title=&#34;step 11&#34;&gt;
&lt;img alt=&#34;step 12&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/12.png&#34; title=&#34;step 12&#34;&gt;
&lt;img alt=&#34;step 13&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/13.png&#34; title=&#34;step 13&#34;&gt;
&lt;img alt=&#34;step 14&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/14.png&#34; title=&#34;step 14&#34;&gt;
&lt;img alt=&#34;step 15&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/15.png&#34; title=&#34;step 15&#34;&gt;
&lt;img alt=&#34;step 16&#34; src=&#34;https://raw.githubusercontent.com/peter-mcconnell/gpt_sql_test_generator/master/media/16.png&#34; title=&#34;step 16&#34;&gt;&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
