[Cython] Bindings performance issue

Robert Bradshaw robertwb at math.washington.edu
Thu Jun 2 07:49:02 CEST 2011


On Wed, Jun 1, 2011 at 7:26 AM, Vitja Makarov <vitja.makarov at gmail.com> wrote:
> 2011/6/1 mark florisson <markflorisson88 at gmail.com>:
>> On 31 May 2011 20:25, Vitja Makarov <vitja.makarov at gmail.com> wrote:
>>> Hi!
>>>
>>> Is bindings performance issue valuable?
>>>
>>> $ cat bindbench.pyx
>>> def wo_bindings():
>>>    pass
>>>
>>> def outer():
>>>    def inner():
>>>        pass
>>>    return inner
>>> with_bindings = outer()
>>>
>>> $ python
>>>>>> import timeit
>>>>>> timeit.repeat('with_bindings()', setup='from bindbench import wo_bindings, with_bindings', repeat=1, number=100000000)
>>> [6.169871807098389]
>>>>>> timeit.repeat('wo_bindings()', setup='from bindbench import wo_bindings, with_bindings', repeat=1, number=100000000)
>>> [4.609416961669922]
>>>
>>> PyCBindings makes it 1.3 (difference is about 15ns on my laptop) times
>>> slower for CPython interpreter execution.
>>> As CPython has some optimizations for CFunctions and PyCFunctions.
>>>
>>> Does it make sense for us? Or we can easily switch to bindings?
>>>
>>> --
>>> vitja.
>>> _______________________________________________
>>> cython-devel mailing list
>>> cython-devel at python.org
>>> http://mail.python.org/mailman/listinfo/cython-devel
>>>
>>
>> I think switching should be fine, if you'd desperately need the speed
>> you'd be calling c(p)def functions from Cython. In fact, when the
>> fused cfunction will be ready it will be even slightly slower, as it
>> overrides the tp_call. But perhaps that should really be made into a
>> subclass...

Yes, this should be a subclass, slowing all calls down is a bad idea.

>> Anyway, would you use these for Python classes and module-level def
>> functions (and closures) only, or would you also use them in extension
>> classes? Because I found at least a bit of problem there, as extension
>> class methods get 'self' passed as the first argument to the C
>> function (as PyCFunctionObject.m_self), whereas methods in Python
>> classes get 'self' passed in the args tuple (and the m_self is
>> unused).
>>
>
> Recently I've found a problem with static methods (__new__ for
> example) of inner classes (classes created inside a function, for
> instance)
> I think binding version should be used for all regular def functions
> (defs, staticmethods, classmethods and so on).

+1 to moving that way. (Well, static and class methods bind
differently, right?)

> I also think that it's better to rename binding_PyCFunction_Type to
> something like CyFunctionType and make it more like PyFunction.

+1

Is there any advantage to the method descriptors (other than that
they're easier for a human to write?)

I think that small speed regression for better compatibility is OK if
we add a directive to not create binding functions. (It'd be nice if
we could work around it, but that's hard as CPython has special
hooks...) The bigger issue is that the binding behavior is backwards
incompatible, and perhaps in a subtle way. Perhaps we need to have a
phase where all currently non-binding functions that will become
binding functions will raise an error (or at least a warning) to wean
people off of the old behavior before making a switch.

- Robert


More information about the cython-devel mailing list