Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed1.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.028 X-Spam-Evidence: '*H*': 0.94; '*S*': 0.00; 'else:': 0.03; 'string': 0.09; '3),': 0.09; 'exec': 0.09; 'executes': 0.09; 'lookup': 0.09; 'runs': 0.10; 'python': 0.11; 'creates': 0.14; 'bytecode': 0.16; 'closures,': 0.16; 'comparison.': 0.16; 'deletes': 0.16; 'factory': 0.16; 'fetches': 0.16; 'parse,': 0.16; 'sec': 0.16; 'subject:skip:e 10': 0.16; 'test).': 0.16; 'trying': 0.19; 'example': 0.22; 'byte': 0.24; 'case.': 0.24; 'passes': 0.24; 'earlier': 0.24; 'looks': 0.24; 'second': 0.26; 'header:In-Reply- To:1': 0.27; 'function': 0.29; 'bigger': 0.30; 'message- id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; "d'aprano": 0.31; 'fast.': 0.31; 'markup': 0.31; 'steven': 0.31; 'stuff': 0.32; 'test': 0.35; 'received:google.com': 0.35; 'executing': 0.36; 'object,': 0.36; 'doing': 0.36; 'two': 0.37; 'step': 0.37; 'skip:& 10': 0.38; 'to:addr:python-list': 0.38; 'skip:& 20': 0.39; 'does': 0.39; 'to:addr:python.org': 0.39; 'skip:p 20': 0.39; 'read': 0.60; 'skip:t 30': 0.61; 'new': 0.61; 'first': 0.61; 'times': 0.62; 'offer': 0.62; '8bit%:10': 0.64; 'map': 0.64; 'more': 0.64; 'finally': 0.65; 'here': 0.66; 'between': 0.67; '\xc2\xa0\xc2\xa0': 0.74; 'savings': 0.81; 'alternative.': 0.84; 'compiles': 0.84; 'xslt': 0.84; 'gender': 0.91; 'ratio': 0.91; 'mrs': 0.96 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=aUUVIRQZErt0w0w7eCF8nJIS0xsC77f3f8biQDNXL9A=; b=LlzNq9JMgEe5Y/af1t4KWdvmz5yrGuDPQyivSw1ldPsULhIia9yzuZxQjBRAkiOgUM qH9phbCCmFWOl8EN3ZGELvoz6Vf/1e+Re65CfMIsoWywIUuptdRqQ6lLfTazZO53dDn/ F+CrSDTnZq/JamHnbXhollwmTVch1i5n45EqhTvA49U8pvZKVAFY/GhHQgZB0G7e6Lyh tO+7FbyfZ6MOe0uyQw4MOLI7Ca0poOmVt7JZILU49WtpzaxHEhVp3wpyIa3XzkS2tVAD GaoppDVfj0QgMKwMMyJ6RabYwVxVrjBtxI6FFJibhGrXOgRYMuiEVjTzQv3hk4VIvWOz icHg== MIME-Version: 1.0 X-Received: by 10.194.88.131 with SMTP id bg3mr4681578wjb.99.1421226156418; Wed, 14 Jan 2015 01:02:36 -0800 (PST) In-Reply-To: <54b592ac$0$12995$c3e8da3$5496439d@news.astraweb.com> References: <54b592ac$0$12995$c3e8da3$5496439d@news.astraweb.com> Date: Wed, 14 Jan 2015 10:02:36 +0100 Subject: Re: Performance in exec environnements From: Jean-Baptiste Braun To: python-list@python.org Content-Type: multipart/alternative; boundary=089e010d849e32ebaa050c99003a X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 135 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1421226164 news.xs4all.nl 2956 [2001:888:2000:d::a6]:58404 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:83739 --089e010d849e32ebaa050c99003a Content-Type: text/plain; charset=UTF-8 2015-01-13 22:48 GMT+01:00 Steven D'Aprano < steve+comp.lang.python@pearwood.info>: > So you have been comparing: > > 2 > > versus > > exec('1+1') > > > The first case just fetches a reference to a pre-existing int object, and > then deletes the reference. That's fast. > > The second case: > > - creates a new string '1+1' > - does a global lookup to find the built-in exec function > - passes the string to the function > - the function then parses that string and compiles it to byte-code > - runs the keyhole optimizer over it > - and finally executes the byte code for "2", same as above. > > Only the last step is the same as your earlier test case. > What I don't understand is the ratio between test 2 / 4 and test 1 / 3. Let 0.0229 sec be the execution time to read a bytecode (1st test). Executing two times that bytecode takes 0.042 sec (test 3), which looks coherent. Let 11.6 sec be the execution time to call the global exec, parse, do some stuff and read a bytecode (test 2). I'm trying to understand why does doing the same thing and reading one more bytecode is much longer (15.7 sec) in comparison. > Bigger savings come from avoiding exec. Instead, try to use factory > functions, closures, etc. If you give an example of what you are trying to > generate with exec, we may be able to offer an alternative. > I think I'm going to compile before exec'ing. What I'm trying to do is to map a transformation description in a markup langage (XSLT) in python to improve execution time. Here is a simplification of what it looks like : XSLT : <xsl:choose> <xsl:when test="gender='M'"> Mr </xsl:when> <xsl:otherwise> Mrs </xsl:otherwise> </xsl:choose> Generated python : print('') if gender == 'M': print('Mr') else: print('Mrs') print('') --089e010d849e32ebaa050c99003a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
2015= -01-13 22:48 GMT+01:00 Steven D'Aprano <steve+comp.= lang.python@pearwood.info>:
So you have been comparing:

=C2=A0 =C2=A0 2

versus

=C2=A0 =C2=A0 exec('1+1')


The first case just fetches a reference to a pre-existing int object, and then deletes the reference. That's fast.

The second case:

- creates a new string '1+1'
- does a global lookup to find the built-in exec function
- passes the string to the function
- the function then parses that string and compiles it to byte-code
- runs the keyhole optimizer over it
- and finally executes the byte code for "2", same as above.

Only the last step is the same as your earlier test case.
<= div>What I don't understand is the ratio between test 2 / 4 and test 1 = / 3.

Let 0.0229 sec be the execution time to read a bytecode (1st te= st). Executing two times that bytecode takes 0.042 sec (test 3), which loo= ks coherent.

Let 11.6 sec be the execution time to call the global e= xec, parse, do some stuff and read a bytecode (test 2). I'm trying to u= nderstand why does doing the same thing and reading one more bytecode is mu= ch longer (15.7 sec) in comparison.
=C2=A0
Bigger savings come from avoiding exec. Instead, try to use factory
functions, closures, etc. If you give an example of what you are trying to<= br> generate with exec, we may be able to offer an alternative.
I think I'= m going to compile before exec'ing.

What I'm tryi= ng to do is to map a transformation description in a markup langage (XSLT) = in python to improve execution time. Here is a simplification of what it lo= oks like :

XSLT :
<title>
=C2=A0<xsl:choose>
=C2=A0 <xsl:when test=3D"= gender=3D'M'">
=C2=A0=C2=A0 Mr
= =C2=A0 </xsl:when>
=C2=A0 <xsl:otherwise>
=C2=A0=C2=A0 Mrs
=C2=A0 </xsl:otherwise>
=C2=A0</xsl:choose>
</title>

Generated python :
print('<title>&#= 39;)
if gender =3D=3D 'M':
=C2=A0=C2=A0= =C2=A0 print('Mr')
else:
=C2=A0=C2=A0= =C2=A0 print('Mrs')
print('</title>')
--089e010d849e32ebaa050c99003a--