Re: Is there a better way to create a list of None objects?

2021-08-12 Thread Matthieu Dartiailh

You can achieve the same result by writing:
[None] * 8

Comparing both cases in IPython I get:

In [1]: %timeit list((None,)*8)
110 ns ± 0.785 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [2]: %timeit [None] * 8
88.2 ns ± 0.432 ns per loop (mean ± std. dev. of 7 runs, 1000 loops 
each)


So the list multiplication appears a bit faster.

Best

Matthieu

Le 8/12/2021 à 10:57 AM, Stephen Tucker a écrit :

Hi,

I thought I'd share the following piece of code that I have recently written
(a) to check that what I have done is reasonable - even optimum,
(b) to inform others who might be wanting to do similar things, and
(c) to invite comment from the community.

---

#

# Yes: Create an empty list of Band Limits for this language

#

# Note. The rather complicated logic on the right-hand side of the

#   assignment below is used here because none of the following

#   alternatives had the desired effect:

#

# Logic Effect

#

# [None * 8]TypeError: unsupported operand type(s) for *: ...

# [(None) * 8]  TypeError: unsupported operand type(s) for *: ...

# [((None)) * 8]TypeError: unsupported operand type(s) for *: ...

# [(None,) * 8] [(None, None, None, None, None, None, None, None)]

# list ((None) * 8) TypeError: unsupported operand type(s) for *: ...

#

diclll_BLim [thisISO_] = list ((None,) * 8)


---

Thanks in anticipation.

Stephen Tucker.


--
https://mail.python.org/mailman/listinfo/python-list


Calling an unbound method in C using the Public API

2018-08-29 Thread Matthieu Dartiailh
Hi,

I am one of the maintainer of the atom library (https://github.com/nucleic/atom 
). This library provides low-memory footprint 
Python objects, descriptors and containers enforcing type validation, 
implements the observer pattern. 

For list, we basically subclass the standard Python list in C++ and add the 
required checks/notifications to some methods (in particular insert, pop and 
sort). To call the method of standard list object on our custom object, the 
original author chose to directly access the c-function inside the MethodDef 
and call it (by first casting to the proper function pointer type).

Starting with Python 3.7, insert, pop and sort use the FASTCALL calling 
convention, which means that the signature of the function stored inside the 
MethodDef have changed. I have a working solution, but it involves to use a lot 
of the CPython private C-API. In particular I needed to access:
_PyCFunctionFast
_PyCFunctionFastWithKeywords
_PyStack_UnpackDict

I tried to look at the public C API for a way to call an unbound method with a 
minimal cost (in term of speed and memory). It seems to me, but please correct 
me if I am wrong, that one cannot call a MethodDef using only the public API. 
To use the public C API, one has to use PyCFunction_Call (or a variant) that 
expect a PyCFunctionObject which binds a the MethodDef to an instance. In my 
case, to avoid creating a temporary PyCFunctionObject each time I call 
list.insert on my custom subclass instance, I have to store that 
PyCFunctionObject for each instance. But this means storing  7 
PyCFunctionObject per instance (one for each method of list I need to wrap). So 
I can either use the public API and increase the memory footprint or slow down 
the code by creating PyCFunctionObject for each call, or use large amount of 
the private API.

Am I missing something ? 

Best regards

Matthieu

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling an unbound method in C using the Public API

2018-09-05 Thread Matthieu Dartiailh
Thanks Serhiy. This does come with a performance penalty (in particular for 
function taking keyword arguments) but this is to be expected. Also the 
PyList_Insert solution does not sadly work for all the methods that I need to 
wrap.

Best

Matthieu

> On Aug 30, 2018, at 11:09 AM, Serhiy Storchaka  wrote:
> 
> 29.08.18 17:33, Matthieu Dartiailh пише:
>> I tried to look at the public C API for a way to call an unbound method with 
>> a minimal cost (in term of speed and memory). It seems to me, but please 
>> correct me if I am wrong, that one cannot call a MethodDef using only the 
>> public API. To use the public C API, one has to use PyCFunction_Call (or a 
>> variant) that expect a PyCFunctionObject which binds a the MethodDef to an 
>> instance. In my case, to avoid creating a temporary PyCFunctionObject each 
>> time I call list.insert on my custom subclass instance, I have to store that 
>> PyCFunctionObject for each instance. But this means storing  7 
>> PyCFunctionObject per instance (one for each method of list I need to wrap). 
>> So I can either use the public API and increase the memory footprint or slow 
>> down the code by creating PyCFunctionObject for each call
>>  , or use large amount of the private API.
>> Am I missing something ?
> 
> In general, you need to cache the unbound method object, and call it with 
> self as the first argument.
> 
> list_insert = PyObject_GetAttrString((PyObject *)&PyList_Type, "insert");
> ...
> res = PyObject_CallFunctionObjArgs(list_insert, self, index, value, NULL);
> 
> But in the particular case of the insert method it will be easier and more 
> efficient to use PyList_Insert().
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list