diff options
Diffstat (limited to 'docs')
7 files changed, 115 insertions, 6 deletions
diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle.py b/docs/examples/userguide/early_binding_for_speed/rectangle.py new file mode 100644 index 000000000..cd534d051 --- /dev/null +++ b/docs/examples/userguide/early_binding_for_speed/rectangle.py @@ -0,0 +1,22 @@ +@cython.cclass +class Rectangle: + x0: cython.int + y0: cython.int + x1: cython.int + y1: cython.int + + def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int): + self.x0 = x0 + self.y0 = y0 + self.x1 = x1 + self.y1 = y1 + + def area(self): + area = (self.x1 - self.x0) * (self.y1 - self.y0) + if area < 0: + area = -area + return area + +def rectArea(x0, y0, x1, y1): + rect = Rectangle(x0, y0, x1, y1) + return rect.area() diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx index de70b0263..b58f6534b 100644 --- a/docs/examples/userguide/early_binding_for_speed/rectangle.pyx +++ b/docs/examples/userguide/early_binding_for_speed/rectangle.pyx @@ -1,7 +1,10 @@ + cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 + + def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0 self.y0 = y0 diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py new file mode 100644 index 000000000..ee2a14fb8 --- /dev/null +++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.py @@ -0,0 +1,26 @@ +@cython.cclass +class Rectangle: + x0: cython.int + y0: cython.int + x1: cython.int + y1: cython.int + + def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int): + self.x0 = x0 + self.y0 = y0 + self.x1 = x1 + self.y1 = y1 + + @cython.cfunc + def _area(self) -> cython.int: + area: cython.int = (self.x1 - self.x0) * (self.y1 - self.y0) + if area < 0: + area = -area + return area + + def area(self): + return self._area() + +def rectArea(x0, y0, x1, y1): + rect: Rectangle = Rectangle(x0, y0, x1, y1) + return rect._area() diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx index 1933326d2..3b64d766b 100644 --- a/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx +++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cdef.pyx @@ -1,13 +1,17 @@ + cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 + + def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0 self.y0 = y0 self.x1 = x1 self.y1 = y1 + cdef int _area(self): cdef int area = (self.x1 - self.x0) * (self.y1 - self.y0) if area < 0: diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py new file mode 100644 index 000000000..670f340a4 --- /dev/null +++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.py @@ -0,0 +1,23 @@ +@cython.cclass +class Rectangle: + x0: cython.int + y0: cython.int + x1: cython.int + y1: cython.int + + def __init__(self, x0: cython.int, y0: cython.int, x1: cython.int, y1: cython.int): + self.x0 = x0 + self.y0 = y0 + self.x1 = x1 + self.y1 = y1 + + @cython.ccall + def area(self)-> cython.int: + area: cython.int = (self.x1 - self.x0) * (self.y1 - self.y0) + if area < 0: + area = -area + return area + +def rectArea(x0, y0, x1, y1): + rect: Rectangle = Rectangle(x0, y0, x1, y1) + return rect.area() diff --git a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx index f8b7d86a8..53f2a8ad2 100644 --- a/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx +++ b/docs/examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx @@ -1,15 +1,19 @@ + cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 + + def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0 self.y0 = y0 self.x1 = x1 self.y1 = y1 + cpdef int area(self): - area = (self.x1 - self.x0) * (self.y1 - self.y0) + cdef int area = (self.x1 - self.x0) * (self.y1 - self.y0) if area < 0: area = -area return area diff --git a/docs/src/userguide/early_binding_for_speed.rst b/docs/src/userguide/early_binding_for_speed.rst index 9bb8cf724..4a442d973 100644 --- a/docs/src/userguide/early_binding_for_speed.rst +++ b/docs/src/userguide/early_binding_for_speed.rst @@ -6,6 +6,9 @@ Early Binding for Speed ************************** +.. include:: + ../two-syntax-variants-used + As a dynamic language, Python encourages a programming style of considering classes and objects in terms of their methods and attributes, more than where they fit into the class hierarchy. @@ -22,7 +25,15 @@ use of 'early binding' programming techniques. For example, consider the following (silly) code example: -.. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle.pyx +.. tabs:: + + .. group-tab:: Pure Python + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle.py + + .. group-tab:: Cython + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle.pyx In the :func:`rectArea` method, the call to :meth:`rect.area` and the :meth:`.area` method contain a lot of Python overhead. @@ -30,7 +41,15 @@ In the :func:`rectArea` method, the call to :meth:`rect.area` and the However, in Cython, it is possible to eliminate a lot of this overhead in cases where calls occur within Cython code. For example: -.. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cdef.pyx +.. tabs:: + + .. group-tab:: Pure Python + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cdef.py + + .. group-tab:: Cython + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cdef.pyx Here, in the Rectangle extension class, we have defined two different area calculation methods, the efficient :meth:`_area` C method, and the @@ -46,10 +65,18 @@ dual-access methods - methods that can be efficiently called at C level, but can also be accessed from pure Python code at the cost of the Python access overheads. Consider this code: -.. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx +.. tabs:: + + .. group-tab:: Pure Python + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cpdef.py + + .. group-tab:: Cython + + .. literalinclude:: ../../examples/userguide/early_binding_for_speed/rectangle_cpdef.pyx -Here, we just have a single area method, declared as :keyword:`cpdef` to make it -efficiently callable as a C function, but still accessible from pure Python +Here, we just have a single area method, declared as :keyword:`cpdef` or with ``@ccall`` decorator +to make it efficiently callable as a C function, but still accessible from pure Python (or late-binding Cython) code. If within Cython code, we have a variable already 'early-bound' (ie, declared |