Le mar. 23 juin 2020 à 03:47, Neil Schemenauer
<nas-pyt...@arctrix.com> a écrit :
> One final comment: I think even if we manage to cleanup the API and
> make it friendly for other Python implementations, there is going to
> be a fair amount of overhead.  If you look at other "managed
> runtimes" that just seems unavoidable (e.g. Java, CLR, V8, etc).
> You want to design the API so that you maximize the amount of useful
> work done with each API call.  Using something like
> PyList_GET_ITEM() to iterate over a list is not a good pattern.  So
> keep in mind that an extension API is going to have some overhead.

A large part of the PEP 620 is already implemented:
https://www.python.org/dev/peps/pep-0620/#summary

So far, I didn't notice any major performance issue, but you're right
that the PEP itself can only make performance as good or worse, but
not better.

The PEP only prevents to specialize code in third party code, CPython
continues to have full access to all internals like structures.

CPython internals already use specialized code. For example,
_PyTuple_ITEMS() gives access to PyObject** which is denied for 3rd
party code in the PEP.

The question is for extensions like numpy which do rely on internals
to emit faster code.

--

In HPy, the question was asked as well. If I recall correctly, instead
of making assumptions about object layouts depending on its type, new
protocols should be added to query access to an object in a specific
way.

For example, we can consider continuing to provide raw access to a
PyObject** array, but an object can reply "sorry, I don't support this
PyObject** protocol". Also, I expect to have a function call to notify
the object when the PyObject** view is not longer needed. Something
like Py_buffer protocol PyBuffer_Release(). Maybe an object can
generate a temporary PyObject** view which requires to allocate
resources (like memory) and the release function would release these
resources.

Pseudo-code:

void iterate(PyObject *obj)
{
PyObjectPP_View view;

if (PyObjectPP_View_Get(&view, obj)) {
  // fast-path: the object provides a PyObject** view
  for (Py_ssize_t i=0; i < view.len; i++ {
    PyObject *item = view.array[i];
    ...
  }
  PyObjectPP_View_Release(&view);
}
else {
  // slow code path using PySequence_GetItem() or anything else
  ...
}

Maybe PyObjectPP_View_Get() should increment the object reference
counter to ensure that the object cannot be destroyed in the loop (if
the loop calls arbitrary Python code), and PyObjectPP_View_Release()
would decrement its reference counter.

"PyObjectPP_View" protocol looks like PySequence_Fast() API, but IMO
PySequence_Fast() is not generic enough. For example, the first issue
is that it cannot reply "no, sorry, the object doesn't support
PyObject**". It always creates a temporary list if the object is not a
tuple or a list, that may be inefficient for a large sequence.

Also, the "view" protocol should be allowed to query other types than
just PyObject**. For example, what if I would like to iterate on a
sequence of integers? bytes, array.array and memoryview can be seen as
sequences of integers.

See also HPy notes on these ideas:
https://github.com/pyhandle/hpy/blob/master/docs/xxx-unsorted-notes.txt

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/632CV42376SWVYAZTHG4ROOV2HRHOVZ7/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to