Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: =?UTF-8?Q?Mike_M=c3=bcller?= Newsgroups: de.comp.lang.python Subject: Re: [Python-de] strings zusammensetzen. Date: Wed, 30 Aug 2017 16:14:35 +0200 Organization: Python Academy GmbH & Co. KG Lines: 88 Message-ID: References: <40c6ccec-4cbc-9614-dbdd-9e88cd1dccf0@gmx.de> <1273b1e6-734a-b955-81c6-f851144f46ba@python-academy.de> Reply-To: mmueller@python-academy.de Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: news.uni-berlin.de AxFRSunWvlDDuK+ut+rtyAvTKTuk7vuHfICiam/6TqXg== Return-Path: X-Original-To: python-de@python.org Delivered-To: python-de@mail.python.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 In-Reply-To: Content-Language: de-DE X-Authenticated-Sender: mmueller@python-academy.de X-Virus-Scanned: Clear (ClamAV 0.99.2/23736/Tue Aug 29 22:34:38 2017) X-BeenThere: python-de@python.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Die Deutsche Python Mailingliste List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <1273b1e6-734a-b955-81c6-f851144f46ba@python-academy.de> X-Mailman-Original-References: <40c6ccec-4cbc-9614-dbdd-9e88cd1dccf0@gmx.de> Xref: csiph.com de.comp.lang.python:4885 Am 30.08.17 um 11:53 schrieb Walter Dörwald: > On 30 Aug 2017, at 7:26, Hermann Riemann wrote: > >> Am 29.08.2017 um 17:21 schrieb Walter Dörwald: >> >>> Python 3.6.2 (default, Jul 26 2017, 16:42:24) >>> Type 'copyright', 'credits' or 'license' for more information >>> IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help. >>> In [1] ▶ base, revision, suffix = "foo", "bar", "baz" >>> In [2] ▶ %timeit base + revision + suffix >>> 208 ns ± 0.532 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) >>> In [3] ▶ %timeit '%s%s%s' % (base, revision, suffix) >>> 315 ns ± 1.55 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) >>> In [4] ▶ %timeit '{}{}{}'.format(base, revision, suffix) >>> 462 ns ± 1.23 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) >>> In [5] ▶ %timeit f'{base}{revision}{suffix}' >>> 14.6 ns ± 0.00911 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops >>> each) Die konkrete Umsetzung ist bei Zeitmessungen immer wichtig. Anstatt des Zugriffs auf die globalen Variablen: %timeit '{}{}{}'.format(base, revision, suffix) 421 ns ± 4.23 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) die Anfangswerte direkt mit %%time zu setzen: %%timeit base, revision, suffix = "foo", "bar", "baz" '{}{}{}'.format(base, revision, suffix) 367 ns ± 5.77 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) bringt hier ähnliche Ergebnisse. Aber für die Variante mit f-String sieht das anders aus: %timeit f'{base}{revision}{suffix}' 14.1 ns ± 0.127 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each) %%timeit base, revision, suffix = "foo", "bar", "baz" f'{base}{revision}{suffix}' 98.6 ns ± 2.02 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) Die letzte Variante scheint mir die realistischere Variante zu sein. In der schnelleren Variante ist wahrscheinlich Caching im Spiel. Schlussfolgerung: f-Strings sind immer noch schneller, aber halt nicht gleich mehr als eine Größenordnung sondern eher um den Faktor 3-4. Mike >> >> Daraus lese ich: >> a+b+c ist schneller als "%s%s%s"%(a,b,c), >> "%a%b%c"%(a,b,c) ist schneller als  "{}{}{}".format(a,b,c). >> >> Das mit 14.6 ns ist Hinweis, >> das in diesem Fall keine Zwischenwerte der Art (a+b)+c erstellt wurden. > > In [1] ▸ import dis > In [2] ▸ base, revision, suffix = "foo", "bar", "baz" > In [3] ▸ def f(): > ······ ▸     return f'{base}{revision}{suffix}' > ······ ▸ > In [4] ▸ dis.dis(f) >   2           0 LOAD_GLOBAL              0 (base) >               2 FORMAT_VALUE             0 >               4 LOAD_GLOBAL              1 (revision) >               6 FORMAT_VALUE             0 >               8 LOAD_GLOBAL              2 (suffix) >              10 FORMAT_VALUE             0 >              12 BUILD_STRING             3 >              14 RETURN_VALUE > > BUILD_STRING ruft _PyUnicode_JoinArray() auf. Und _PyUnicode_JoinArray() > berechnet einmal den Speicherverbrauch und kopiert dann alle Teile in den > Zielspeicherbereich. > >> Hermann >>    der jetzt wieder eher os.system("rm "+dateiname) >>    statt os.system("rm {}".format(dateiname)) schreiben wird. > > Servus, >    Walter > _______________________________________________ > python-de maillist  -  python-de@python.org > https://mail.python.org/mailman/listinfo/python-de