Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cython: Can I use cppclass instead of class and does it have any performance advantages?

Tags:

class

cython

I'm just starting out with Cython and I tried to replace:

cdef class TestClass:
    int m_A

    def __init__(self, int a):
        self.m_A = a

    cdef void test_method(self):
        print(self.m_A)

    cdef int return_test(self):
        return 1

With:

cdef cppclass TestClassCpp:
    int m_A

    TestClass(int a):
        m_A = a

    void TestMethod():
        print(m_A)

    int ReturnTest():
        return 1

To test, I created a Main function that is called by a script I built to automatically compile the code.

cpdef int Main(str argv):
    # Declare instance of Cython class and run tests
    print("Python")
    cdef TestClass t = TestClass(1)
    t.test_method()
    print(t.return_test())

    # Declare instance of cppclass and run tests
    print("C++")
    cdef TestClassCpp* tc = new TestClass(1)
    tc.TestMethod()
    print(tc.ReturnTest())

    return 0

I think there is some kinda memory issue. I am able to create an instance of the C++ class, and ReturnTest() works, but whenever I print m_A it prints out a random number, not the one that should be in m_A. This leads me to believe the problems could be either in the constructor or in accessing member variables from other methods. I'm doing this in an effort to optimize everything I can. So I though cppclass could be faster than class, but I've got no evidnce of this.

like image 959
user15389823 Avatar asked Oct 27 '25 00:10

user15389823


1 Answers

Ignoring your particular issue: I would strongly recommend against it.

Creating a cppclass from within Cython (as opposed to wrapping cppclass created in C++) is barely documented and you're likely to run into bugs. The issue that you ran into here is one of them. There will be more.

The big advantage of using a cdef class is that you can interact with it from Python. With a cdef cppclass you can't do that, unless you then wrap it in a cdef class (and once you've done that we're well into the realm of "utterly pointless").

If you want to write C++ code then you're usually better writing it in C++, and then writing a minimal wrapper in Cython. Writing it in Cython means you have to understand Cython and C++ and all the places they don't quite link up.

Finally, think long and hard about what you're trying to achieve here:

  • If the answer is "I'm kind of writing C++ therefore I think it will be faster" then that's nonsense/"cargo cult programming" - you can get Cython to produce efficient C or C++ code within a regular function in a regular class.
  • If the answer is "I need to allocate a lot of these classes rapidly, and the reference-counting overhead from Python is becoming a problem" then this approach might be a solution (but there might be other options that don't use barely supported features)

Side note:

I created a Main function that is called by a script I built to automatically compile the code.

cpdef int Main(str argv):

This is also pointless. If you're calling it from a script then just use a regular def function. cpdef offers no benefit here unless it's called extremely frequently from Cython. cpdef is rarely worthwhile.

like image 151
DavidW Avatar answered Oct 29 '25 00:10

DavidW