Commit ec1f46ee authored by gitlab-runner's avatar gitlab-runner
Browse files

render site via gitlab runner

parent 8ec1b316b8e6
Pipeline #16292 passed with stages
in 1 minute and 36 seconds
......@@ -106,11 +106,11 @@ there. Please just check if it imports. If it imports, it should work:</p>
not support refcounting semantics. The following code won't fill the
file immediately, but only after a certain period of time, when the GC
does a collection and flushes the output:</p>
<pre class="code python"><a name="rest_code_6cd25f13156d4cf49ab1529ec991be25-1"></a><span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span>
<pre class="code python"><a name="rest_code_86203d42d2d14fe6b6ff63e121bc13ab-1"></a><span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span>
</pre>
<p>The proper fix is</p>
<pre class="code python"><a name="rest_code_713695a52914412ead2059e3d2d9ac2b-1"></a><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a name="rest_code_713695a52914412ead2059e3d2d9ac2b-2"></a> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span>
<pre class="code python"><a name="rest_code_71df49ad44af453896ad824784d1065e-1"></a><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<a name="rest_code_71df49ad44af453896ad824784d1065e-2"></a> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"stuff"</span><span class="p">)</span>
</pre>
<p>The same problem---not closing your files---can also show up if your
program opens a large number of files without closing them explicitly.
......@@ -124,22 +124,22 @@ places where <code class="docutils literal">close()</code> is missing.</p>
<p>Similarly, remember that you must <code class="docutils literal">close()</code> a non-exhausted
generator in order to have its pending <code class="docutils literal">finally</code> or <code class="docutils literal">with</code>
clauses executed immediately:</p>
<pre class="code python"><a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-1"></a><span class="k">def</span> <span class="nf">mygen</span><span class="p">():</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-2"></a> <span class="k">with</span> <span class="n">foo</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-3"></a> <span class="k">yield</span> <span class="mi">42</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-4"></a>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-5"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mygen</span><span class="p">():</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-6"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-7"></a> <span class="k">break</span> <span class="c1"># foo.__exit__ is not run immediately!</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-8"></a>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-9"></a><span class="c1"># fixed version:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-10"></a><span class="n">gen</span> <span class="o">=</span> <span class="n">mygen</span><span class="p">()</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-11"></a><span class="k">try</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-12"></a> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">gen</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-13"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-14"></a> <span class="k">break</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-15"></a><span class="k">finally</span><span class="p">:</span>
<a name="rest_code_2289fd7841d34d28baf65f3ef16a651a-16"></a> <span class="n">gen</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<pre class="code python"><a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-1"></a><span class="k">def</span> <span class="nf">mygen</span><span class="p">():</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-2"></a> <span class="k">with</span> <span class="n">foo</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-3"></a> <span class="k">yield</span> <span class="mi">42</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-4"></a>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-5"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mygen</span><span class="p">():</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-6"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-7"></a> <span class="k">break</span> <span class="c1"># foo.__exit__ is not run immediately!</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-8"></a>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-9"></a><span class="c1"># fixed version:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-10"></a><span class="n">gen</span> <span class="o">=</span> <span class="n">mygen</span><span class="p">()</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-11"></a><span class="k">try</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-12"></a> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">gen</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-13"></a> <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-14"></a> <span class="k">break</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-15"></a><span class="k">finally</span><span class="p">:</span>
<a name="rest_code_a5baf39eef0c4ebfa01cd1fec7204070-16"></a> <span class="n">gen</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre>
<p>More generally, <code class="docutils literal">__del__()</code> methods are not executed as predictively
as on CPython: they run "some time later" in PyPy (or not at all if
......
......@@ -324,14 +324,14 @@ about "missing Python.h", you may need to install the pypy-dev package.</p>
<p>Get the source code. The preferred way is to checkout the current
trunk using <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a>. The trunk usually works and is of course
more up-to-date:</p>
<pre class="code bash"><a name="rest_code_8c64f4b429a743ccbc3bf4a420b6556e-1"></a>hg clone https://foss.heptapod.net/pypy/pypy
<pre class="code bash"><a name="rest_code_cec964193fb446aca9e67022a1e69079-1"></a>hg clone https://foss.heptapod.net/pypy/pypy
</pre>
<p>The trunk contains PyPy 2. For PyPy 3, switch to the correct branch:</p>
<pre class="code bash"><a name="rest_code_c37e1940e3a34fd3bafe8c062b3968f1-1"></a><span class="c1"># switch to the branch that implements Python 3.7</span>
<a name="rest_code_c37e1940e3a34fd3bafe8c062b3968f1-2"></a>hg update py3.7
<a name="rest_code_c37e1940e3a34fd3bafe8c062b3968f1-3"></a>
<a name="rest_code_c37e1940e3a34fd3bafe8c062b3968f1-4"></a><span class="c1"># switch to the branch that implements Python 3.6</span>
<a name="rest_code_c37e1940e3a34fd3bafe8c062b3968f1-5"></a>hg update py3.6
<pre class="code bash"><a name="rest_code_8155c9a4ef814a6d931fc4713f3e2cb7-1"></a><span class="c1"># switch to the branch that implements Python 3.7</span>
<a name="rest_code_8155c9a4ef814a6d931fc4713f3e2cb7-2"></a>hg update py3.7
<a name="rest_code_8155c9a4ef814a6d931fc4713f3e2cb7-3"></a>
<a name="rest_code_8155c9a4ef814a6d931fc4713f3e2cb7-4"></a><span class="c1"># switch to the branch that implements Python 3.6</span>
<a name="rest_code_8155c9a4ef814a6d931fc4713f3e2cb7-5"></a>hg update py3.6
</pre>
<p>Alternatively, get one of the following smaller packages for the source at
the same revision as the above binaries:</p>
......@@ -346,19 +346,19 @@ the same revision as the above binaries:</p>
</li>
<li>
<p>Enter the <code class="docutils literal">goal</code> directory:</p>
<pre class="code bash"><a name="rest_code_b761c6a854d040a4a3032ee3f3763e0d-1"></a><span class="nb">cd</span> pypy/pypy/goal
<pre class="code bash"><a name="rest_code_09c9fa20f78940eb9b51423e785cbeb0-1"></a><span class="nb">cd</span> pypy/pypy/goal
</pre>
</li>
<li>
<p>Run the <code class="docutils literal">rpython</code> script. Here are the common combinations
of options (works also with <code class="docutils literal">python</code> instead of <code class="docutils literal">pypy</code>;
requires CPython 2.7 or PyPy 2, even to build PyPy 3):</p>
<pre class="code bash"><a name="rest_code_57d16731ed80450783e016f4f4c12164-1"></a><span class="c1"># get the JIT version</span>
<a name="rest_code_57d16731ed80450783e016f4f4c12164-2"></a>pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
<a name="rest_code_57d16731ed80450783e016f4f4c12164-3"></a><span class="c1"># get the no-jit version</span>
<a name="rest_code_57d16731ed80450783e016f4f4c12164-4"></a>pypy ../../rpython/bin/rpython -O2 targetpypystandalone
<a name="rest_code_57d16731ed80450783e016f4f4c12164-5"></a><span class="c1"># get the sandbox version</span>
<a name="rest_code_57d16731ed80450783e016f4f4c12164-6"></a>pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
<pre class="code bash"><a name="rest_code_c5d93c4626a24765b20986b2034426ca-1"></a><span class="c1"># get the JIT version</span>
<a name="rest_code_c5d93c4626a24765b20986b2034426ca-2"></a>pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
<a name="rest_code_c5d93c4626a24765b20986b2034426ca-3"></a><span class="c1"># get the no-jit version</span>
<a name="rest_code_c5d93c4626a24765b20986b2034426ca-4"></a>pypy ../../rpython/bin/rpython -O2 targetpypystandalone
<a name="rest_code_c5d93c4626a24765b20986b2034426ca-5"></a><span class="c1"># get the sandbox version</span>
<a name="rest_code_c5d93c4626a24765b20986b2034426ca-6"></a>pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
</pre>
</li>
<li><p>Enjoy Mandelbrot <code class="docutils literal"><span class="pre">:-)</span></code> It takes on the order of half an hour to
......@@ -386,17 +386,17 @@ used and 2.9 GB if CPython is used. There are two workarounds:</p>
<p>1. use PyPy, not CPython. If you don't have any PyPy so far, not even
an older version, then you need to build one first, with some parts
removed. So, first translate with:</p>
<pre class="code shell"><a name="rest_code_9d1df46809f64693ab6f86a2fa85412b-1"></a>cpython2 rpython -Ojit targetpypystandalone <span class="se">\</span>
<a name="rest_code_9d1df46809f64693ab6f86a2fa85412b-2"></a>--withoutmod-micronumpy --withoutmod-cpyext
<pre class="code shell"><a name="rest_code_0e1bde31d1424b2fa123e49b9ea63f39-1"></a>cpython2 rpython -Ojit targetpypystandalone <span class="se">\</span>
<a name="rest_code_0e1bde31d1424b2fa123e49b9ea63f39-2"></a>--withoutmod-micronumpy --withoutmod-cpyext
</pre>
<p>then copy <code class="docutils literal"><span class="pre">pypy-c</span></code> and <code class="docutils literal">libpypy_c.so</code> somewhere else, and finally
call it with <code class="docutils literal"><span class="pre">...pypy-c</span> <span class="pre">../../rpython/bin/rpython</span> <span class="pre">-Ojit</span></code>.</p>
<p>2. if even using PyPy instead of CPython is not enough, try to tweak
some internal parameters. Example (slower but saves around 400MB):</p>
<pre class="code bash"><a name="rest_code_fda2cc14deda4b02baae852b8fd2dc7c-1"></a><span class="nv">PYPY_DONT_RUN_SUBPROCESS</span><span class="o">=</span><span class="m">1</span> <span class="nv">PYPY_GC_MAX_DELTA</span><span class="o">=</span>200MB <span class="se">\</span>
<a name="rest_code_fda2cc14deda4b02baae852b8fd2dc7c-2"></a>pypy --jit <span class="nv">loop_longevity</span><span class="o">=</span><span class="m">300</span> ../../rpython/bin/rpython <span class="se">\</span>
<a name="rest_code_fda2cc14deda4b02baae852b8fd2dc7c-3"></a>-Ojit --source
<a name="rest_code_fda2cc14deda4b02baae852b8fd2dc7c-4"></a><span class="c1"># then read the next point about --source</span>
<pre class="code bash"><a name="rest_code_eaeedaa7ebb945a399f5f8988c956bc5-1"></a><span class="nv">PYPY_DONT_RUN_SUBPROCESS</span><span class="o">=</span><span class="m">1</span> <span class="nv">PYPY_GC_MAX_DELTA</span><span class="o">=</span>200MB <span class="se">\</span>
<a name="rest_code_eaeedaa7ebb945a399f5f8988c956bc5-2"></a>pypy --jit <span class="nv">loop_longevity</span><span class="o">=</span><span class="m">300</span> ../../rpython/bin/rpython <span class="se">\</span>
<a name="rest_code_eaeedaa7ebb945a399f5f8988c956bc5-3"></a>-Ojit --source
<a name="rest_code_eaeedaa7ebb945a399f5f8988c956bc5-4"></a><span class="c1"># then read the next point about --source</span>
</pre>
</li>
<li><p>You can run translations with <code class="docutils literal"><span class="pre">--source</span></code>, which only builds the C
......@@ -417,9 +417,9 @@ translation and you specify <code class="docutils literal"><span class="pre">--s
<p>Once PyPy is translated from source, a binary package similar to those
provided in the section <a class="reference internal" href="download_advanced.html#default-with-a-jit-compiler">Default (with a JIT Compiler)</a> above can be
created with the <code class="docutils literal">package.py</code> script:</p>
<pre class="code bash"><a name="rest_code_38b00f89163643f1b8ddf27ff55d974c-1"></a><span class="nb">cd</span> ./pypy/pypy/tool/release/
<a name="rest_code_38b00f89163643f1b8ddf27ff55d974c-2"></a>python package.py --help <span class="c1"># for information</span>
<a name="rest_code_38b00f89163643f1b8ddf27ff55d974c-3"></a>python package.py --archive-name pypy-my-own-package-name
<pre class="code bash"><a name="rest_code_5cdd981b28dd4da6b6ee2c85210902c6-1"></a><span class="nb">cd</span> ./pypy/pypy/tool/release/
<a name="rest_code_5cdd981b28dd4da6b6ee2c85210902c6-2"></a>python package.py --help <span class="c1"># for information</span>
<a name="rest_code_5cdd981b28dd4da6b6ee2c85210902c6-3"></a>python package.py --archive-name pypy-my-own-package-name
</pre>
<p>It is recommended to use package.py because custom scripts will
invariably become out-of-date. If you want to write custom scripts
......
......@@ -153,16 +153,16 @@ languages.</p>
build <code class="docutils literal"><span class="pre">pypy-sandbox</span></code> from it (see <a class="reference external" href="download.html#building-from-source">Building from source</a>). These
instructions give you a <code class="docutils literal"><span class="pre">pypy-c</span></code> that you should rename to
<code class="docutils literal"><span class="pre">pypy-sandbox</span></code> to avoid future confusion. Then run:</p>
<pre class="code bash"><a name="rest_code_5cc340229dbc468ea83755d061b7bdbb-1"></a><span class="nb">cd</span> pypy/sandbox
<a name="rest_code_5cc340229dbc468ea83755d061b7bdbb-2"></a>pypy_interact.py path/to/pypy-sandbox
<a name="rest_code_5cc340229dbc468ea83755d061b7bdbb-3"></a><span class="c1"># don't confuse it with pypy/goal/pyinteractive.py!</span>
<pre class="code bash"><a name="rest_code_321b83d5de9a4e0caa2643959a7ba281-1"></a><span class="nb">cd</span> pypy/sandbox
<a name="rest_code_321b83d5de9a4e0caa2643959a7ba281-2"></a>pypy_interact.py path/to/pypy-sandbox
<a name="rest_code_321b83d5de9a4e0caa2643959a7ba281-3"></a><span class="c1"># don't confuse it with pypy/goal/pyinteractive.py!</span>
</pre>
<p>You get a fully sandboxed interpreter, in its own filesystem hierarchy
(try <code class="docutils literal"><span class="pre">os.listdir('/')</span></code>). For example, you would run an untrusted
script as follows:</p>
<pre class="code bash"><a name="rest_code_908559b1939f4b6c8b86f2818ae42718-1"></a>mkdir virtualtmp
<a name="rest_code_908559b1939f4b6c8b86f2818ae42718-2"></a>cp untrusted.py virtualtmp/
<a name="rest_code_908559b1939f4b6c8b86f2818ae42718-3"></a>pypy_interact.py --tmp<span class="o">=</span>virtualtmp pypy-sandbox /tmp/untrusted.py
<pre class="code bash"><a name="rest_code_d9056df084954e6689e000cd8f713301-1"></a>mkdir virtualtmp
<a name="rest_code_d9056df084954e6689e000cd8f713301-2"></a>cp untrusted.py virtualtmp/
<a name="rest_code_d9056df084954e6689e000cd8f713301-3"></a>pypy_interact.py --tmp<span class="o">=</span>virtualtmp pypy-sandbox /tmp/untrusted.py
</pre>
<p>Note that the path <code class="docutils literal">/tmp/untrusted.py</code> is a path inside the sandboxed
filesystem. You don't have to put <code class="docutils literal">untrusted.py</code> in the real <code class="docutils literal">/tmp</code>
......
......@@ -29,7 +29,7 @@ use pypy for your projects and provide detailed feedback
talk to us about how to support Python 3.x
write blog posts or twe">
<meta property="og:type" content="article">
<meta property="article:published_time" content="2021-01-12T14:14:41Z">
<meta property="article:published_time" content="2021-01-12T21:31:31Z">
</head>
<body>
<a href="#content" class="sr-only sr-only-focusable">Skip to main content</a>
......
......@@ -231,13 +231,13 @@ until 2.0.</p>
<div class="section" id="string-concatenation-is-expensive">
<h3>String concatenation is expensive</h3>
<p>In CPython, you may want to replace:</p>
<pre class="code python"><a name="rest_code_f9da9041eece423497a85c0243d70b38-1"></a><span class="n">s</span> <span class="o">=</span> <span class="n">head</span> <span class="o">+</span> <span class="n">body</span> <span class="o">+</span> <span class="n">maybe</span> <span class="o">+</span> <span class="n">tail</span>
<pre class="code python"><a name="rest_code_bd47e961cc7d46618c96b4954336fb57-1"></a><span class="n">s</span> <span class="o">=</span> <span class="n">head</span> <span class="o">+</span> <span class="n">body</span> <span class="o">+</span> <span class="n">maybe</span> <span class="o">+</span> <span class="n">tail</span>
</pre>
<p>with the admittedly less readable:</p>
<pre class="code python"><a name="rest_code_9173786eb30545da9965f103faf20f7e-1"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%(head)s%(body)s%(maybe)s%(tail)s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">locals</span><span class="p">()</span>
<pre class="code python"><a name="rest_code_b22ee3a4a64941f2b6a8b78801b7f1c0-1"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%(head)s%(body)s%(maybe)s%(tail)s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">locals</span><span class="p">()</span>
</pre>
<p>or even:</p>
<pre class="code python"><a name="rest_code_78e26a698f174f2a8feda7cece25ce94-1"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{head}{body}{maybe}{tail}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="nb">locals</span><span class="p">())</span>
<pre class="code python"><a name="rest_code_e6e75ed07a4e44c488febea9290858fd-1"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{head}{body}{maybe}{tail}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="nb">locals</span><span class="p">())</span>
</pre>
<p>Both of the latter forms avoid multiple-allocation overhead.
But PyPy's JIT makes the overhead of intermediate concatenations
......@@ -245,8 +245,8 @@ go away in linear code that keeps the number of concatenations
small, bound and constant. (And <code class="docutils literal">locals()</code> is rather slow
with PyPy's JIT.)</p>
<p>On the other hand, in code like this with a string-valued foo() function:</p>
<pre class="code python"><a name="rest_code_5e616ea341b6483088ca1b956549a944-1"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mylist</span><span class="p">:</span>
<a name="rest_code_5e616ea341b6483088ca1b956549a944-2"></a> <span class="n">s</span> <span class="o">+=</span> <span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<pre class="code python"><a name="rest_code_bfbfd002ec9a41f2a03e5176c669bb97-1"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mylist</span><span class="p">:</span>
<a name="rest_code_bfbfd002ec9a41f2a03e5176c669bb97-2"></a> <span class="n">s</span> <span class="o">+=</span> <span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</pre>
<p>the JIT cannot optimize out intermediate copies. This code is
actually quadratic in the total size of the mylist strings due to
......@@ -254,10 +254,10 @@ repeated string copies of ever-larger prefix segments. (Such code
is always fine for bytearrays, because in this case <code class="docutils literal">+=</code> is an
in-place operation.)</p>
<p>This:</p>
<pre class="code python"><a name="rest_code_b8bb050bf8ca436982cff2bc2f6fa990-1"></a><span class="n">parts</span> <span class="o">=</span> <span class="p">[]</span>
<a name="rest_code_b8bb050bf8ca436982cff2bc2f6fa990-2"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mylist</span><span class="p">:</span>
<a name="rest_code_b8bb050bf8ca436982cff2bc2f6fa990-3"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<a name="rest_code_b8bb050bf8ca436982cff2bc2f6fa990-4"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span>
<pre class="code python"><a name="rest_code_d80d68c55b5a4fc492a074dbd64c7f10-1"></a><span class="n">parts</span> <span class="o">=</span> <span class="p">[]</span>
<a name="rest_code_d80d68c55b5a4fc492a074dbd64c7f10-2"></a><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mylist</span><span class="p">:</span>
<a name="rest_code_d80d68c55b5a4fc492a074dbd64c7f10-3"></a> <span class="n">parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<a name="rest_code_d80d68c55b5a4fc492a074dbd64c7f10-4"></a><span class="n">s</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span>
</pre>
<p>can be much faster because all the string concatenation in the last
line creates exactly one new string object with one C-level copy
......
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PyPy</title><link>https://www.pypy.org/</link><description>A Faster Python</description><atom:link href="https://www.pypy.org/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2021 &lt;a href="mailto:pypy-dev@pypy.org"&gt;The PyPy Team&lt;/a&gt; </copyright><lastBuildDate>Wed, 13 Jan 2021 04:27:33 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs></channel></rss>
\ No newline at end of file
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PyPy</title><link>https://www.pypy.org/</link><description>A Faster Python</description><atom:link href="https://www.pypy.org/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2021 &lt;a href="mailto:pypy-dev@pypy.org"&gt;The PyPy Team&lt;/a&gt; </copyright><lastBuildDate>Wed, 13 Jan 2021 04:28:39 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs></channel></rss>
\ No newline at end of file
......@@ -7,50 +7,50 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://www.pypy.org/</loc>
<lastmod>2021-01-13T04:26:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/archive.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/blog/</loc>
<lastmod>2021-01-12T22:02:00Z</lastmod>
<lastmod>2021-01-12T21:31:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/categories/</loc>
<lastmod>2021-01-12T22:02:00Z</lastmod>
<lastmod>2021-01-12T21:31:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/compat.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/contact.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/download.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/download_advanced.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/features.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/howtohelp.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/people.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
<url>
<loc>https://www.pypy.org/performance.html</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</url>
</urlset>
\ No newline at end of file
......@@ -7,10 +7,10 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<sitemap>
<loc>https://www.pypy.org/rss.xml</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</sitemap>
<sitemap>
<loc>https://www.pypy.org/sitemap.xml</loc>
<lastmod>2021-01-13T04:27:00Z</lastmod>
<lastmod>2021-01-13T04:28:00Z</lastmod>
</sitemap>
</sitemapindex>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment