[Cython] Bindings performance issue

Robert Bradshaw robertwb at math.washington.edu
Fri Jun 3 00:22:25 CEST 2011


On Thu, Jun 2, 2011 at 3:04 PM, mark florisson
<markflorisson88 at gmail.com> wrote:
> On 2 June 2011 23:59, Robert Bradshaw <robertwb at math.washington.edu> wrote:
>> On Thu, Jun 2, 2011 at 2:45 PM, mark florisson
>> <markflorisson88 at gmail.com> wrote:
>>> On 2 June 2011 23:34, Robert Bradshaw <robertwb at math.washington.edu> wrote:
>>>> On Thu, Jun 2, 2011 at 2:21 PM, mark florisson
>>>> <markflorisson88 at gmail.com> wrote:
>>>>> On 2 June 2011 23:13, Robert Bradshaw <robertwb at math.washington.edu> wrote:
>>>>>> On Thu, Jun 2, 2011 at 2:03 PM, mark florisson
>>>>>> <markflorisson88 at gmail.com> wrote:
>>>>>>
>>>>>>>>>> If anyone is assigning a Cython function to an object and then using
>>>>>>>>>> it they're counting on the current non-binding behavior, and it will
>>>>>>>>>> break. The speed is probably a lesser issue, which is what benchmarks
>>>>>>>>>> are for.
>>>>>>>>>
>>>>>>>>> If you're binding functions to classes without expecting it to ever
>>>>>>>>> bind, you don't really have bitching rights when stuff breaks later
>>>>>>>>> on. You should have been using staticmethod() to begin with. And we
>>>>>>>>> never said that our functions would never bind :)
>>>>>>>>
>>>>>>>> No, you're assigning it to an object, counting on being able to call
>>>>>>>> it later on. E.g. the following is legal (though contrived in this
>>>>>>>> example):
>>>>>>>>
>>>>>>>> sage: class A:
>>>>>>>> ....:     pass
>>>>>>>> ....:
>>>>>>>> sage: a = A()
>>>>>>>> sage: a.foo = max
>>>>>>>> sage: a.foo([1,2,3])
>>>>>>>> 3
>>>>>>>>
>>>>>>>> If instead of len, it was one of our functions, then it would be bad
>>>>>>>> to suddenly change the semantics, because it could still run but
>>>>>>>> produce bad answers (e.g. if we had implemented max, suddenly a would
>>>>>>>> be included in the comparison). This is why I proposed raising an
>>>>>>>> explicit error as an intermediate step.
>>>>>>>>
>>>>>>>> If we don't promise anything, the contract is whatever the code does.
>>>>>>>> That's the problem with not having a specification (which would be
>>>>>>>> really nice, but is a lot of work).
>>>>>>>
>>>>>>> Functions on objects never get bound, they only get bound if they are
>>>>>>> on the class. So your code would still work with binding functions.
>>>>>>
>>>>>> True. It would still break "A.foo = max" though. I'm not saying we
>>>>>> should support or encourage this, but lets break it hard before we
>>>>>> break it subtly.
>>>>>
>>>>> Again, such code is highly fragile and frankly incorrect to begin
>>>>> with, as it's based on the assumption that "Cython functions" never
>>>>> get bound.
>>>>
>>>> I agree, but I bet there's code out there depending on it, in
>>>> particular workarounds for our current broken semantics will
>>>> themselves break.
>>>
>>> Workarounds wouldn't break, as they would wrap the non-binding
>>> function in another object, and implement __get__ to return a new
>>> object that, when called, would call the original function with 'self'
>>> as the first argument.
>>
>> Depends on the workaround. I'm thinking workarounds like "oh, self
>> isn't getting passed, guess I'll have to pass it manually here..."
>
> Ah, something like functools.partial. Yeah, that'd break :)
>
>>>>> Getting functions (defined outside of class bodies) to bind
>>>>> in classes is a feature, I sometimes found myself to want it. So
>>>>> basically an error would be fine, but it would prevent normal usage as
>>>>> we have it in Python.
>>>>
>>>> The error would just be for a transition period.
>>>
>>> The transition period would be for an entire release?
>>
>> Yes, though hopefully a much shorter release cycle than this last one.
>> I just haven't had time to fix those remaining failing Sage tests, and
>> we keep merging in more and more stuff (which is good, but we're well
>> overdue for a release by now.)
>
> Ok. Then perhaps it would be better to merge the support for fused
> types in the next release? I won't be available until the 6th of July
> for coding, so until then we'd be stuck with cython.fused_type() in a
> ctypedef.

Well, it's such a cool feature :). More to the point, it's not nearly
as invasive (i.e. compiling existing code will still pretty much work
the way it always has).

- Robert


More information about the cython-devel mailing list