brandtbucher / automap

High-performance autoincremented integer-valued mappings. 🗺️

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage of `PyVarObject`

flexatone opened this issue · comments

FAMIType, FAMType and others are defined as PyVarObjects, using the PyVarObject_HEAD_INIT and PyObject_VAR_HEAD conventions. However, PyObject_NewVar is never used, so perhaps using PyVarObjects is not necessary?

All types need the PyVarObject header. Everywhere you see PyVarObject_HEAD_INIT is initializing the header of the type itself, not its instances.

With that said, I also see now that FAMObject, FAMVObject, and FAMIObject structs (for the instances) start with PyObject_VAR_HEAD, which adds an ob_size member to each of these structs. However, we aren't using this member or the Py_SIZE macro anywhere, and it isn't being initialized with PyObject_NewVar, as you note.

So, it's probably not needed, and these three structs can just start with PyObject_HEAD instead, saving one word of memory per instance.

Many thanks for your response.

I can confirm that using PyObject_HEAD instead of PyObject_VAR_HEAD seems to show now difference.

But I am still confused about using PyVarObject_HEAD_INIT. The docs say "This is a macro which expands to initialization values for a new PyVarObject type"; whereas for PyObject_HEAD_INIT the docs say "This is a macro which expands to initialization values for a new PyObject type".

However, if I try to use PyObject_HEAD_INIT instead of PyVarObject_HEAD_INIT, the code works fine, but I get a warning I cannot figure out how to remove: "missing braces around initializer [-Wmissing-braces]".

I notice in the CPython source PyObject_HEAD_INIT is used only once! (in moduleobject.h), whereas PyVarObject_HEAD_INIT is used hundreds of times, often with exactly the arrangement you suggest, where we have PyObject_HEAD for the instance and PyVarObject_HEAD_INIT in the type. We see the same arrangement here:

https://github.com/python/cpython/blob/main/Doc/extending/newtypes_tutorial.rst

But again, this is confusing as the docs seem to suggest that PyVarObject_HEAD_INIT on the type should go with a PyObject_VAR_HEAD on the instance, and a PyObject_HEAD_INIT on the type should go with a PyObject_HEAD on the instance.

If you would like, I can submit a PR for this project that uses PyObject_HEAD to reduce the instance size.