Re: [f2py] f2py speed

Pearu Peterson <[email protected]> Sat, 23 Feb 2013 21:39:24 +0200
Newsgroups gmane.comp.python.f2py.user
Message-ID <CAPpwKcyxbmeRHN58DN8jhYFZ0rsCVR8B=Hy7guZ-bMkPWOc66Q@mail.gmail.com>
--===============8200118739169684922==
Content-Type: multipart/alternative; boundary=047d7bfcef7413abeb04d6697700

--047d7bfcef7413abeb04d6697700
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

On Sat, Feb 23, 2013 at 7:29 PM, Gabor Kalman <[email protected]> wrote:

>   I=92m a relatively new user of f2py.
> To test what performance advantage I can get with f2py, I have created (a
> somewhat artificially) simple script.
> First I describe it and then I will show the source code.
>
> 1. Description:
>
> Take 3 constants (3 integers) and multiply those together in a double loo=
p
> of range  of 10,000 (i.e. 10**8 computations).
> If I use a PYTHON ONLY scrip, it took 28 sec. (with Windows 7 on a Toshib=
a
> C655D, Python 27)
> If I =93buried=94 the computation in a GFORTRAN sub, it required only 0.0=
15
> sec.
>
> I can=92t find anything wrong with my source codes. So are these results
> plausible?
>


Yes, the results are expected.

First, these are as they are due to the simple fact that Python is
interpreted language (operation types are resolved at run time) while
Fortran is compiled language (operation types are resolved at compile time)=
.

Second, your benchmark is simply unfair to Python and is not representable
for assessing the performance advantage of f2py. You should use your
application code, written in Python or f2py wrapped Fortran, to get most
appropriate assessment.

In general, when you want to speed up your Python code, first determine
which parts of it take most runtime and write only those parts in Fortran
and call these via wrapper generators such us f2py.

Some illustrative examples how to speed up Python follow below.

Note that already simple python loop takes some time as object creation
operations are expensive in Python (same list is created 10000 times):
>>> def main10(z):
    for i in range(10000):
        for j in range(10000):
            pass
   ...:
>>> %time main10(0)
CPU times: user 2.04 s, sys: 0.00 s, total: 2.04 s
Wall time: 2.04 s

This can be accelerated using range generator:
>>> def main10x(z):
    for i in xrange(10000):
        for j in xrange(10000):
            pass
   ....:
>>>
>>> %time main10x(0)
CPU times: user 1.39 s, sys: 0.00 s, total: 1.39 s
Wall time: 1.38 s

or using cached range:

>>> def main10c(z, r=3Drange(10000)):
    for i in r:
        for j in r:
            pass
   ....:
>>> %time main10c(0)
CPU times: user 1.05 s, sys: 0.00 s, total: 1.05 s
Wall time: 1.05 s

Now, when adding operations, the result depends on operand types:
>>> def main10o(z, r=3Drange(10000)):
    for i in r:
        for j in r:
            zz =3D 2*z
   ....:
>>> %time main10o(0)
CPU times: user 3.46 s, sys: 0.00 s, total: 3.46 s
Wall time: 3.45 s
>>> %time main10o(0.0)
CPU times: user 6.16 s, sys: 0.00 s, total: 6.16 s
Wall time: 6.17 s



Pearu

--047d7bfcef7413abeb04d6697700
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Sat, Feb 23, 2013 at 7:29 PM, Gabor Kalman <span dir=3D"ltr">&lt=
;<a href=3D"mailto:[email protected]" target=3D"_blank">kalman_g@verizon=
.net</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div dir=3D"ltr">
<div style=3D"font-size:12pt;font-family:&#39;Calibri&#39;">
<div>I=92m a relatively new user of f2py. </div>
<div>To test what performance advantage I can get with f2py, I have created=
 (a=20
somewhat artificially) simple script.</div>
<div>First I describe it and then I will show the source code.</div>
<div>=A0</div>
<div>1. Description:</div>
<div>=A0</div>
<div>Take 3 constants (3 integers) and multiply those together in a double =
loop=20
of range=A0 of 10,000 (i.e. 10**8 computations).</div>
<div>If I use a PYTHON ONLY scrip, it took 28 sec. (with Windows 7 on a Tos=
hiba=20
C655D, Python 27)</div>
<div>If I =93buried=94 the computation in a GFORTRAN sub, it required only =
0.015=20
sec.</div>
<div>=A0</div>
<div>I can=92t find anything wrong with my source codes. So are these resul=
ts=20
plausible?</div></div></div></div></blockquote><div><br><br></div><div>Yes,=
 the results are expected.<br><br>First, these are as they are due to the s=
imple fact that Python is interpreted language (operation types are resolve=
d at run time) while Fortran is compiled language (operation types are reso=
lved at compile time).<br>
<br>Second, your benchmark is simply unfair to Python and is not representa=
ble for assessing the performance advantage of f2py. You should use your ap=
plication code, written in Python or f2py wrapped Fortran, to get most appr=
opriate assessment.<br>
</div><div><br></div><div>In general, when you want to speed up your Python=
 code, first determine which parts of it take most runtime and write only t=
hose parts in Fortran and call these via wrapper generators such us f2py.<b=
r>
</div><div><br></div><div>Some illustrative examples how to speed up Python=
 follow below.<br><br>Note that already simple python loop takes some time =
as object creation operations are expensive in Python (same list is created=
 10000 times):<br>
&gt;&gt;&gt; def main10(z):<br>=A0=A0=A0 for i in range(10000):<br>=A0=A0=
=A0=A0=A0=A0=A0 for j in range(10000):<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
 pass<br>=A0=A0 ...:=A0=A0=A0=A0=A0=A0=A0=A0 <br>&gt;&gt;&gt; %time main10(=
0)<br>CPU times: user 2.04 s, sys: 0.00 s, total: 2.04 s<br>
Wall time: 2.04 s<br><br></div><div>This can be accelerated using range gen=
erator:<br>&gt;&gt;&gt; def main10x(z):<br>=A0=A0=A0 for i in xrange(10000)=
:<br>=A0=A0=A0=A0=A0=A0=A0 for j in xrange(10000):<br>=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 pass<br>=A0=A0 ....:=A0=A0=A0=A0=A0=A0=A0=A0 <br>
&gt;&gt;&gt; <br>&gt;&gt;&gt; %time main10x(0)<br>CPU times: user 1.39 s, s=
ys: 0.00 s, total: 1.39 s<br>Wall time: 1.38 s<br><br></div><div>or using c=
ached range:<br><br></div><div>&gt;&gt;&gt; def main10c(z, r=3Drange(10000)=
):<br>
=A0=A0=A0 for i in r:<br>=A0=A0=A0=A0=A0=A0=A0 for j in r:<br>=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 pass<br>=A0=A0 ....:=A0=A0=A0=A0=A0=A0=A0=A0 <br>&gt;=
&gt;&gt; %time main10c(0)<br>CPU times: user 1.05 s, sys: 0.00 s, total: 1.=
05 s<br>Wall time: 1.05 s<br><br></div><div>Now, when adding operations, th=
e result depends on operand types:<br>
&gt;&gt;&gt; def main10o(z, r=3Drange(10000)):<br>=A0=A0=A0 for i in r:<br>=
=A0=A0=A0=A0=A0=A0=A0 for j in r:<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 zz =
=3D 2*z<br>=A0=A0 ....:=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 <br>&gt;&gt;&gt=
; %time main10o(0)<br>CPU times: user 3.46 s, sys: 0.00 s, total: 3.46 s<br=
>
Wall time: 3.45 s<br>&gt;&gt;&gt; %time main10o(0.0)<br>CPU times: user 6.1=
6 s, sys: 0.00 s, total: 6.16 s<br>Wall time: 6.17 s<br><br></div><div><br>=
</div><div><br></div><div>Pearu</div><div><br></div></div></div></div>

--047d7bfcef7413abeb04d6697700--


--===============8200118739169684922==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
f2py-users mailing list
f2py-users-Y4l6ocDipWCuvFJfX82//[email protected]
http://cens.ioc.ee/mailman/listinfo/f2py-users

--===============8200118739169684922==--