Re: [Cython] AddTraceback() slows down generators

2012-01-29 Thread Stefan Behnel
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

2012-01-29 Thread Stefan Behnel
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

2012-01-29 Thread mark florisson
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

2012-01-29 Thread Vitja Makarov
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

2012-01-29 Thread Wes McKinney
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

2012-01-29 Thread Fernando Perez
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