Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!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.023 X-Spam-Evidence: '*H*': 0.95; '*S*': 0.00; 'cpython': 0.05; 'interpreter': 0.05; 'subject:Python': 0.06; 'differently': 0.07; 'computed': 0.09; 'subject:Does': 0.09; 'cc:addr:python-list': 0.11; 'python': 0.11; '2),': 0.16; 'algorithm.': 0.16; 'cc:name:python list': 0.16; 'exponential': 0.16; 'itself,': 0.16; 'underlying': 0.16; 'url:file': 0.16; 'wrote:': 0.18; "python's": 0.19; '(in': 0.22; 'cc:addr:python.org': 0.22; 'accommodate': 0.24; 'integer': 0.24; 'skip': 0.24; 'math': 0.24; 'question': 0.24; 'cc:2**0': 0.24; '(see': 0.26; 'equivalent': 0.26; 'header :In-Reply-To:1': 0.27; 'point': 0.28; 'function': 0.29; 'converting': 0.30; 'message-id:@mail.gmail.com': 0.30; 'comments': 0.31; 'libraries': 0.31; 'object.': 0.31; 'operators': 0.31; 'trivial': 0.31; 'handled': 0.32; 'url:python': 0.33; 'proceed': 0.33; 'december': 0.35; 'case,': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'library.': 0.36; 'subject:?': 0.36; 'url:org': 0.36; 'two': 0.37; 'expensive': 0.39; 'read': 0.60; 'logs': 0.60; 'problems.': 0.60; 'mentioned': 0.61; 'john': 0.61; 'first': 0.61; 'here:': 0.62; "you'll": 0.62; 'different': 0.65; 'taking': 0.65; 'between': 0.67; 'power': 0.76; '100': 0.79; 'multiplying': 0.84; 'oscar': 0.84; 'url:cpython': 0.84; 'steps.': 0.91; 'choice.': 0.93; '2013': 0.98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=XkyF2WufmnZML8V/RNilf8tJTwaFF/5ZwRrFCym602k=; b=OBHVT97lxagIoJdUKlXJsY6Yh7dvwhSixkNU6QY8a0jHwTXdFB+8+Sqa7swlK5IxbO tY4CIy47ZoLFGy3ln6jy5+O8jQPiulfvxJ5R4D+Z2s+0sCUh1v8xl2HHzRF5RB/p7xoM 6Br/ibEDHTd4DadLPTGW16Ovpluf7iOOibs+NFEaEMekyGWCVMm5MSP2DQjmjViu5Afj IPAyn+l2+8hO2xwnEhD2KD7CVVOBzaBGRkRcKuo3W2MV+lhEFyd66Bxjqp/PQYG0B8JX 0sR68ioTW97ODZImo7sXxjlG3dao3sVRBbeO1654NkLsCX0zeRJE/4hgLmbvsXLlpViA pG0g== X-Received: by 10.221.39.195 with SMTP id tn3mr3000051vcb.2.1386363489283; Fri, 06 Dec 2013 12:58:09 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <5ea86e1b-f5b5-49d1-acfb-22ee4d9a1f16@googlegroups.com> References: <5ea86e1b-f5b5-49d1-acfb-22ee4d9a1f16@googlegroups.com> From: Oscar Benjamin Date: Fri, 6 Dec 2013 20:57:49 +0000 Subject: Re: Does Python optimize low-power functions? To: John Ladasky Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: Python List 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: 42 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1386363497 news.xs4all.nl 2965 [2001:888:2000:d::a6]:53179 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:61182 On 6 December 2013 18:16, John Ladasky wrote: > The following two functions return the same result: > > x**2 > x*x > > But they may be computed in different ways. The first choice can accommo= date non-integer powers and so it would logically proceed by taking a logar= ithm, multiplying by the power (in this case, 2), and then taking the anti-= logarithm. But for a trivial value for the power like 2, this is clearly a= wasteful choice. Just multiply x by itself, and skip the expensive log an= d anti-log steps. > > My question is, what do Python interpreters do with power operators where= the power is a small constant, like 2? Do they know to take the shortcut? As mentioned this will depend on the interpreter and on the type of x. Python's integer arithmetic is exact and unbounded so switching to floating point and using approximate logarithms is a no go if x is an int object. For CPython specifically, you can see here: http://hg.python.org/cpython/file/07ef52e751f3/Objects/floatobject.c#l741 that for floats x**2 will be equivalent to x**2.0 and will be handled by the pow function from the underlying C math library. If you read the comments around that line you'll see that different inconsistent math libraries can do things very differently leading to all kinds of different problems. For CPython if x is an int (long) then as mentioned before it is handled by the HAC algorithm: http://hg.python.org/cpython/file/07ef52e751f3/Objects/longobject.c#l3934 For CPython if x is a complex then it is handled roughly as you say: for x**n if n is between -100 and 100 then multiplication is performed using the "bit-mask exponentiation" algorithm. Otherwise it is computed by converting to polar exponential form and using logs (see also the two functions above this one): http://hg.python.org/cpython/file/07ef52e751f3/Objects/complexobject.c#l151 Oscar