Need help with very basics.

18 views
Skip to first unread message

dgpb

unread,
Jun 11, 2025, 6:15:23 PMJun 11
to cython-users
Would appreciate some help with this a lot.

So in C I have something like:
```C
static PyObject *
myfoo() {
    Py_ssize_t n = 10
    stack = PyMem_Malloc(n * sizeof(PyObject *));
    if (stack == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    stack[0] = PyTuple_New(10)
    PyObject *ret = stack[0]
    if (stack != small_stack) {
            PyMem_Free(stack);
        }
    return stack[0]
}
```

Can I write the same in Cython Pure Python mode?

Prakhar Goel

unread,
Jun 12, 2025, 11:56:51 AMJun 12
to cython...@googlegroups.com
A little confused: what's "stack" for and what's "small_stack"?

In general, I think you'd be able to write most of that at least in Cython's native language. I haven't used Pure Python mode that much myself so I'm not sure there.
--
________________________
Warm Regards
Prakhar Goel


--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/cython-users/3608eb74-ef9d-42a7-a4bc-51135afcd589n%40googlegroups.com.

dg pb

unread,
Jun 12, 2025, 7:17:21 PMJun 12
to cython...@googlegroups.com
There is no small stack. I just need efficient array for Python objects.

```C
static PyObject *
myfoo() {
    Py_ssize_t n = 10
    stack = PyMem_Malloc(n * sizeof(PyObject *));
    if (stack == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    stack[0] = PyTuple_New(10)
    PyObject *ret = stack[0]
    PyMem_Free(stack);
    return stack[0]
}
```

Prakhar Goel

unread,
Jun 14, 2025, 12:12:28 AMJun 14
to cython...@googlegroups.com
Just trying to understand the purpose of this algorithm. Why malloc the stack in the first place? Why not just store the tuple pointer in a variable?

--
________________________
Warm Regards
Prakhar Goel
--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.

dg pb

unread,
Jun 14, 2025, 12:32:21 AMJun 14
to cython...@googlegroups.com
Ok, so what I really need is a faster list/array for python objects.

`list` access is already well optimized, but I want to get faster than that.
And it does seem to be faster when I just create a stack in `C` when I do extensions.

da-woods

unread,
Jun 14, 2025, 2:33:15 AMJun 14
to cython...@googlegroups.com

You could write this relatively easily using Cython's pyx file mode.

It'd just be a case of doing something like:

```
from cpython.object cimport PyObject
from cpython.mem cimport PyMem_Malloc

cdef extern from "Python.h":
    PyObject *PyTuple_New(Py_ssize_t size)
    # ... other definitions

def myfoo():
    py_ssize_t n = 10
    cdef PyObject** stack = <PyObject**>PyMem_Malloc(sizeof(PyObject*)*n)
    if stack == NULL:
        raise MemoryError()
    try:
        stack[0] = PyTuple_New(10)
        # other code presumably goes here
        return <object>stack[0]
    finally:
        PyMem_Free(stack)
```

You'll have to manually do some of the definitions yourself because Cython's own wrappings defined the return type as `object` which means it'll try to handle the reference counting - this doesn't seem to be what you want.

I doubt that pure-Python mode is complete enough to support all is. It doesn't seem hugely useful to try to use pure-Python because there's no chance that it can usefully run in Python. So I'd stick to the "traditional" Cython syntax for this kind of code.

David

dg pb

unread,
Jun 14, 2025, 3:26:09 AMJun 14
to cython...@googlegroups.com

Prakhar Goel

unread,
Jun 14, 2025, 6:31:48 AMJun 14
to cython...@googlegroups.com
I'm not sure you'll get much benefit from this though. Python's own impls (list and tuple) are fairly efficiently written and increasingly have special handling in the interpreter which won't be available for whatever you come up with. 

If you use your structure purely in C code, you might be able to elide a bunch of ref-counting and None checks. I've written code like that and it can be done but you need to be very careful. And it didn't help that much. I got far better results by restructuring the leaves of my data structures (i.e. using raw ints, floats, bit vectors, etc...) but of course that can be a very invasive change and is very specific to your exact problem. 

Benchmark early and often.
--
________________________
Warm Regards
Prakhar Goel
Reply all
Reply to author
Forward
0 new messages