[issue782] Order of calls changes performance

New submission from Ismael <ismaelgfk@gmail.com>: In the following code, the order of calls alters the performance. First case: running calc first, then calc_arr second: ismael@chaos:~/Escritorio$ ~/pypy/bin/pypy slow.py Section time: 0.865699052811 -- Calc Section time: 0.757493019104 -- Calc_arr So, here, best time for calc_arr is 0.75s. It doesn't matter if I run it 10 times, it still about that fast. Now, running calc_arr first and calc second: ismael@chaos:~/Escritorio$ ~/pypy/bin/pypy slow.py Section time: 0.400774002075 -- Calc_arr Section time: 1.53682088852 -- Calc The method that took 0.7s now takes 0.4! And the one that took 0.8s now takes 1.5! For comparison, PyPy latest (45351) is even worse: ismael@chaos:~/Escritorio$ ~/pypy/pypylatest/pypy-c-jit-45351-2630c86662b4-linux64/bin/pypy slow.py Section time: 0.940190792084 -- Calc Section time: 0.925091981888 -- Calc_arr ismael@chaos:~/Escritorio$ ~/pypy/pypylatest/pypy-c-jit-45351-2630c86662b4-linux64/bin/pypy slow.py Section time: 0.418694019318 -- Calc_arr Section time: 1.73908495903 -- Calc Code modified from http://technicaldiscovery.blogspot.com/2011/07/speeding-up-python-again.html class Timer(object): def __enter__(self): self.start = time.time() def __exit__(self, exc_type, exc_val, tb): print "Section time: ", time.time() - self.start import array import time dx = 0.1 dy = 0.1 dx2 = dx*dx dy2 = dy*dy def py_update(u,nx,ny): for i in xrange(1,nx-1): for j in xrange(1, ny-1): u[i][j] = ((u[i+1][j] + u[i-1][j]) * dy2 + (u[i][j+1] + u[i][j-1]) * dx2) / (2*(dx2+dy2)) def calc(N, Niter=100): u = [[0.0]*N for i in xrange(N)] for i in xrange(N): u[0][i] = 1.0 for i in range(Niter): py_update(u,N,N) return u def calc_arr(N, Niter=100): u = [array.array("d", [0.0])*N for i in xrange(N)] for i in xrange(N): u[0][i] = 1.0 for i in range(Niter): py_update(u,N,N) return u #Compare this: with Timer(): u = calc_arr(150,1000) with Timer(): u = calc(150,1000) #To this (comment the previous section): with Timer(): u = calc(150,1000) with Timer(): u = calc_arr(150,1000) ---------- messages: 2741 nosy: Ismael, pypy-issue priority: bug release: 1.5 status: unread title: Order of calls changes performance ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________

Armin Rigo <armin.rigo@gmail.com> added the comment: This is due to the fact that they are both using the same helper, py_update(), with a different type of argument. This causes the 2nd run to slow down. If we duplicate py_update() and call one or the other in calc() and calc_arr(), then calc() takes always ~0.4 secs and calc_arr() always ~0.9 secs, independently on the order in which they run. This may be considered worth investigating, but may require some careful tweaks in the JIT. I would say it's a task "for later maybe"... ---------- nosy: +arigo status: unread -> chatting ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________

Fijal <fijall@gmail.com> added the comment: Isn't the thing going to pretty much disappear once we merge hakan's branches for improving bridges? ---------- nosy: +fijal ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________

Fijal <fijall@gmail.com> added the comment: A bit of nitpicking (I can fix it myself). _reduce_any_all_impl is returning an impl which is almost entirely different depending on a flag, it's also called once with flag = True and once with False. Wouldn't it be simpler to just have descr_any and descr_all as separate functions without all the metaprogramming? ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________

Fijal <fijall@gmail.com> added the comment: Uh sorry, previous comment went to the wrong issue ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________

Carl Friedrich Bolz <cfbolz@gmx.de> added the comment: the two variants are the same speed nowadays. ---------- nosy: +cfbolz status: chatting -> resolved ________________________________________ PyPy bug tracker <tracker@bugs.pypy.org> <https://bugs.pypy.org/issue782> ________________________________________
participants (4)
-
Armin Rigo
-
Carl Friedrich Bolz
-
Fijal
-
Ismael