Re: [Cython] AddTraceback() slows down generators
Vitja Makarov, 28.01.2012 21:41: > 2012/1/29 Stefan Behnel: >> Vitja Makarov, 28.01.2012 20:58: >>> 2012/1/28 mark florisson: On 28 January 2012 19:41, Vitja Makarov wrote: > 2012/1/28 Stefan Behnel: >> Here's a general take on a code object cache for exception propagation. >> >> https://github.com/scoder/cython/commit/ad18e0208 >> >> When I raise an exception in test code that propagates through a Python >> call hierarchy of four functions before being caught, the cache gives me >> something like a 2x speedup in total. Not bad. When I do the same for >> cdef >> functions, it's more like 4-5x. >> >> The main idea is to cache the objects in a reallocable C array and bisect >> into it based on the C code "__LINE__" of the exception, which should be >> unique enough for a given module. >> >> It's a global cache that doesn't limit the lifetime of code objects >> (well, >> up to the lifetime of the module, obviously). I don't know if that's a >> problem because the number of code objects is only bounded by the number >> of >> exception origination points in the C source code, which is usually quite >> large. However, only a tiny fraction of those will ever raise or >> propagate >> an exception in practice, so the real number of cached code objects will >> be >> substantially smaller. >> >> Maybe thorough test suites with lots of failure testing would notice a >> difference in memory consumption, even though a single code objects isn't >> all that large either... > > We already have --no-c-in-traceback flag that disables C line numbers > in traceback. What's about enabling it by default? > I'm quite attached to that feature actually :), it would be pretty annoying to disable that flag every time. And what would disabling that option gain, as the current code still formats the filename and function name. >>> >>> It's rather useful for developers or debugging. Most of the people >>> don't need it. >> >> Not untrue. However, at least a majority of developers should be able to >> make use of it when it's there, and code is several times more often built >> for testing and debugging than for production. So I consider it a virtue >> that it's on by default. >> >> >>> Here is simple benchmark: >>> # upstream/master: 6.38ms >>> # upstream/master (no-c-in-traceback): 3.07ms >>> # scoder/master: 1.31ms >>> def foo(): >>> raise ValueError >>> >>> def testit(): >>> cdef int i >>> for i in range(1): >>> try: >>> foo() >>> except: >>> pass >>> >>> Stefan's branch wins but: >>> - there is only one item in the cache and it's always hit >> >> Even if there were substantially more, binary search is so fast you'd >> hardly notice the difference. > > Yes, I'm a little bit worried about insertions. I know, that's O(n), but it only strikes when a new exception is raised or propagated from a code line that has never raised an exception before. That makes it *very* unlikely that it hits a performance critical spot. > With --no-c-in-traceback python lineno should be used as a key. Good call, I added that. https://github.com/scoder/cython/commit/8b50da874#diff-0 That means that using this option additionally improves the caching performance now because you get less code objects overall, at most one per Cython source code line (as opposed to C source code line). Stefan ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] AddTraceback() slows down generators
Stefan Behnel, 28.01.2012 21:14: > mark florisson, 28.01.2012 20:07: >> On 28 January 2012 18:38, Stefan Behnel wrote: >>> Stefan Behnel, 27.01.2012 09:02: any exception *propagation* is still substantially slower than necessary, and that's a general issue. >>> >>> Here's a general take on a code object cache for exception propagation. >>> [...] >> Nice. I have a question, couldn't you save the frame object instead of >> the code object? > > Technically, yes. However, eventually, I'd like to make the CodeObject > constant for the whole function and let CPython calculate the Python code > source line based on the frame's "f_lasti" field when the line number is > actually accessed. > > For now, I wouldn't mind cashing the whole frame until the above > optimisation gets implemented. Actually, I was wrong. The frame object cannot be cached because it is mutable and even gets modified when building the stack trace call hierarchy. So caching the frame instance may have user visible side effects. Stefan ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] AddTraceback() slows down generators
On 29 January 2012 12:10, Stefan Behnel wrote: > Stefan Behnel, 28.01.2012 21:14: >> mark florisson, 28.01.2012 20:07: >>> On 28 January 2012 18:38, Stefan Behnel wrote: Stefan Behnel, 27.01.2012 09:02: > any exception *propagation* is > still substantially slower than necessary, and that's a general issue. Here's a general take on a code object cache for exception propagation. [...] >>> Nice. I have a question, couldn't you save the frame object instead of >>> the code object? >> >> Technically, yes. However, eventually, I'd like to make the CodeObject >> constant for the whole function and let CPython calculate the Python code >> source line based on the frame's "f_lasti" field when the line number is >> actually accessed. >> >> For now, I wouldn't mind cashing the whole frame until the above >> optimisation gets implemented. > > Actually, I was wrong. The frame object cannot be cached because it is > mutable and even gets modified when building the stack trace call > hierarchy. So caching the frame instance may have user visible side effects. > > Stefan > ___ > cython-devel mailing list > cython-devel@python.org > http://mail.python.org/mailman/listinfo/cython-devel Ah right, the f_back attribute? ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
[Cython] Bug in multiplied tuple optimization
Investigating sage-tests segfaults I found that this code causes sigsegv: def foo(): return (0,) * len('abc') foo() -- vitja. ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Slow traceback reconstruction in IPython between 0.15.1 and master
On Fri, Jan 27, 2012 at 2:40 AM, Stefan Behnel wrote: > Wes McKinney, 26.01.2012 18:56: >> Just wanted to bring this issue to your guys' attention in case you >> knew what was responsible for this: >> >> https://github.com/ipython/ipython/issues/1317#issuecomment-3652550 >> >> I traced down the problem (with git bisect) to a seemingly innocuous >> commit referenced in that GitHub thread. The issue seemed to only >> present itself in IPython, so likely there was some problem with >> inspecting the Cython frames for giving context around the full >> traceback. > > That's not impossible. Traceback frames behave differently in Cython for > two reasons: a) because they are only being constructed after the fact in > an error handling case, not for normal functions, and b) because Cython > doesn't have real code objects for inspection and fakes them in a rather > ad-hoc way. For example, there is currently no function signature > information in them, and line number computation doesn't use the normal > CPython way that matches the byte code position with a compressed line > table. Instead, Cython creates a new code object for a given line on the > fly and just pretends that the function starts there. This usually works > well enough for a traceback, but this kind of differences makes it quite > possible that IPython makes assumptions about inspection here that Cython > doesn't meet. > > In another thread ("AddTraceback() slows down generators"), I was proposing > to cache the code object for a given function. That would then imply > providing a (fake) byte code position map as well and would make it easier > to provide static signature information, thus improving the overall > compatibility with the code objects that CPython creates. > > Note that it's unclear without further investigation if the problem you ran > into really has to do with these internal details. I'm just raising a > possible explanation here. > > Stefan > ___ > cython-devel mailing list > cython-devel@python.org > http://mail.python.org/mailman/listinfo/cython-devel My curiosity about this issue was overwhelming so I profiled and tracked down what's going on. Basically looks like a bug in IPython and the fact that it appeared then disappeared depending on the Cython version was completely idiosyncratic. Should have known since the Cython commit that git bisect yielded was so innocuous. More on this here: https://github.com/ipython/ipython/issues/1317 - Wes ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
Re: [Cython] Slow traceback reconstruction in IPython between 0.15.1 and master
On Sun, Jan 29, 2012 at 9:38 AM, Wes McKinney wrote: > More on this > here: > > https://github.com/ipython/ipython/issues/1317 Thanks for your persistence! For those on the cython list, it should be fixed soon, Thomas already has a PR up. Cheers, f ___ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel