Skip to content

Commit e402d18

Browse files
performance improvements
1 parent f5ed9d2 commit e402d18

5 files changed

Lines changed: 92 additions & 80 deletions

File tree

cython_src/utility/extended_perlin_noise.pyx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
1+
# cython: language_level=3
2+
13
# Correct import for numpy and accessing its random module
24
from numpy import random as _numpy__random
35
from numpy import empty as _numpy__empty
46
from numpy import float64 as _numpy__float64
57
from numpy import asarray as _numpy__asarray
68
from libc.math cimport floor, pow
79

8-
cdef double fade(double t):
10+
cdef inline double fade(double t) noexcept:
911
"""
1012
🟩 **R** -
1113
"""
1214
return t * t * t * (t * (t * 6 - 15) + 10)
1315

14-
cdef double lerp(double t, double a, double b):
16+
cdef inline double lerp(double t, double a, double b) noexcept:
1517
"""
1618
🟩 **R** -
1719
"""
1820
return a + t * (b - a)
1921

20-
cdef double grad(int hash, double x, double y=0, double z=0):
22+
cdef inline double grad(int hash, double x, double y=0, double z=0) noexcept:
2123
"""
2224
🟩 **R** -
2325
"""
@@ -52,7 +54,7 @@ cdef class ExtendedPerlinNoise:
5254
for i in range(256):
5355
self.permutation[i] = self.permutation[i + 256] = perm[i]
5456

55-
cdef double perlin(self, double x, double y=0, double z=0):
57+
cdef inline double perlin(self, double x, double y=0, double z=0) noexcept:
5658
"""
5759
🟩 **R** -
5860
"""

cython_src/utility/math_utils.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ cpdef double raw_pythag(cnp.ndarray[double, ndim=1] points):
9898
return sqrt(sum)
9999

100100
# Function to normalize a vector
101-
cdef cnp.ndarray[double, ndim=1] normalize(cnp.ndarray[double, ndim=1] v):
101+
cdef inline cnp.ndarray[double, ndim=1] normalize(cnp.ndarray[double, ndim=1] v):
102102
"""
103103
🟩 **R** -
104104
"""

cython_src/utility/number_converter.pyx

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# cython: language_level=3
2+
13
from colorsys import hsv_to_rgb as _colorsys__hsv_to_rgb
24
from colorsys import rgb_to_hsv as _colorsys__rgb_to_hsv
35

@@ -126,106 +128,102 @@ cdef class Color:
126128

127129
cdef class DisplayScalar:
128130
"""
129-
🟩 **R** -
131+
🟩 **R** - Optimized version
130132
"""
131133
cdef double _point
132134
cdef object _logger
133-
cdef int display_height
135+
cdef double display_height
136+
cdef object _display_object # Store reference to avoid repeated lookups
134137

135138
def __init__(self):
136139
"""
137-
🟩 **R** -
140+
🟩 **R** - Optimized
138141
"""
139142
self._point = 0.0
140143
self._logger = _InternalLogger()
141-
self.display_height = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT].get_height()
144+
self._display_object = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT]
145+
self.display_height = self._display_object.get_height()
142146

143-
cpdef void update_display_height(self):
144-
self.display_height = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT].get_height()
147+
cpdef void update_display_height(self) noexcept:
148+
""" Update display height with stored reference """
149+
self.display_height = self._display_object.get_height()
145150

146-
cpdef void set_point(self, double value, str in_type=Constants.CONVENTIONAL_COORDINATES):
151+
cpdef void set_point(self, double value, str in_type) noexcept:
147152
"""
148-
🟩 **R** -
153+
🟩 **R** - Optimized
149154
"""
150155
cdef double half_display_height
151156

152-
if in_type == Constants.CONVENTIONAL_COORDINATES:
157+
if in_type == Constants.CONVENTIONAL_COORDINATES: # Constants.CONVENTIONAL_COORDINATES
153158
self._point = value
154-
elif in_type == Constants.OPENGL_COORDINATES:
155-
half_display_height = self.display_height / 2.0
159+
elif in_type == Constants.OPENGL_COORDINATES: # Constants.OPENGL_COORDINATES
160+
half_display_height = self.display_height * 0.5
156161
self._point = value * half_display_height
157162

158-
cpdef double get_point(self, str out_type=Constants.CONVENTIONAL_COORDINATES):
163+
cpdef double get_point(self, str out_type) noexcept:
159164
"""
160-
🟩 **R** -
165+
🟩 **R** - Optimized
161166
"""
162-
if out_type == Constants.CONVENTIONAL_COORDINATES:
167+
if out_type == Constants.CONVENTIONAL_COORDINATES: # Constants.CONVENTIONAL_COORDINATES
163168
return self._point
164-
elif out_type == Constants.OPENGL_COORDINATES:
165-
return self._point / (self.display_height / 2.0)
169+
elif out_type == Constants.OPENGL_COORDINATES: # Constants.OPENGL_COORDINATES
170+
return self._point / (self.display_height * 0.5)
166171

167172
cdef class DisplayCoordinates:
168173
"""
169-
🟩 **R** -
174+
🟩 **R** - Optimized
170175
"""
171-
cdef list _coordinate
176+
cdef double _coordinate[2] # Use a fixed-size C array
172177
cdef object _logger
173-
cdef tuple display_size
178+
cdef double display_width, display_height
179+
cdef object _display_object # Store reference for performance
174180

175181
def __init__(self):
176182
"""
177-
🟩 **R** -
183+
🟩 **R** - Optimized
178184
"""
179-
self._coordinate = [0.0, 0.0]
185+
self._coordinate[0] = 0.0
186+
self._coordinate[1] = 0.0
180187
self._logger = _InternalLogger()
188+
self._display_object = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT]
189+
self.display_width, self.display_height = self._display_object.get_size()
181190

182-
self.display_size = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT].get_size()
183-
184-
cpdef void update_display_size(self):
185-
self.display_size = _Registry.pmma_module_spine[Constants.DISPLAY_OBJECT].get_size()
191+
cpdef void update_display_size(self) noexcept:
192+
""" Update display size """
193+
self.display_width, self.display_height = self._display_object.get_size()
186194

187-
cpdef void set_coordinate(self, object coordinate, str in_type=Constants.CONVENTIONAL_COORDINATES):
195+
cpdef void set_coordinate(self, object coordinate, str in_type) noexcept:
188196
"""
189-
🟩 **R** -
197+
🟩 **R** - Optimized
190198
"""
191-
cdef list converted_coordinate
199+
cdef double x, y
192200

193-
if isinstance(coordinate, (list, tuple, _numpy.ndarray)):
194-
converted_coordinate = list(coordinate)
195-
else:
196-
converted_coordinate = [float(coordinate)]
197-
198-
if len(converted_coordinate) == 0:
199-
converted_coordinate = [0.0, 0.0]
200-
elif len(converted_coordinate) == 1:
201-
converted_coordinate.append(0.0)
202-
elif len(converted_coordinate) > 2:
203-
self._logger.log_development("This process is only required for 2D coordinates.")
204-
converted_coordinate = converted_coordinate[:2]
201+
try:
202+
# Assume coordinate is iterable and extract values
203+
x, y = coordinate[0], coordinate[1]
204+
except (IndexError, TypeError):
205+
x, y = 0.0, 0.0 # Default case
205206

206-
cdef double half_display_width, half_display_height, x, y
207+
cdef double half_display_width = self.display_width * 0.5
208+
cdef double half_display_height = self.display_height * 0.5
207209

208-
if in_type == Constants.CONVENTIONAL_COORDINATES:
209-
self._coordinate = converted_coordinate
210-
elif in_type == Constants.OPENGL_COORDINATES:
211-
half_display_width = self.display_size[0] / 2.0
212-
half_display_height = self.display_size[1] / 2.0
213-
x = half_display_width * (converted_coordinate[0] + 1)
214-
y = -half_display_height * (converted_coordinate[1] - 1)
215-
self._coordinate = [x, y]
210+
if in_type == Constants.CONVENTIONAL_COORDINATES: # Constants.CONVENTIONAL_COORDINATES
211+
self._coordinate[0] = x
212+
self._coordinate[1] = y
213+
elif in_type == Constants.OPENGL_COORDINATES: # Constants.OPENGL_COORDINATES
214+
self._coordinate[0] = half_display_width * (x + 1)
215+
self._coordinate[1] = -half_display_height * (y - 1)
216216

217-
cpdef cnp.ndarray[cnp.float32_t, ndim=1] get_coordinate(self, str out_type=Constants.CONVENTIONAL_COORDINATES):
217+
cpdef cnp.ndarray[cnp.float32_t, ndim=1] get_coordinate(self, str out_type):
218218
"""
219-
🟩 **R** -
219+
🟩 **R** - Optimized
220220
"""
221-
cdef double display_width, display_height, x, y
221+
cdef double x, y
222222

223-
if out_type == Constants.CONVENTIONAL_COORDINATES:
224-
return _numpy.array(self._coordinate, dtype=_numpy.float32)
223+
if out_type == Constants.CONVENTIONAL_COORDINATES: # Constants.CONVENTIONAL_COORDINATES
224+
return _numpy.array([self._coordinate[0], self._coordinate[1]], dtype=_numpy.float32)
225225

226-
elif out_type == Constants.OPENGL_COORDINATES:
227-
display_width = self.display_size[0]
228-
display_height = self.display_size[1]
229-
x = (2.0 * self._coordinate[0]) / display_width - 1.0
230-
y = 1.0 - (2.0 * self._coordinate[1]) / display_height
231-
return _numpy.array([x, y], dtype=_numpy.float32)
226+
elif out_type == Constants.OPENGL_COORDINATES: # Constants.OPENGL_COORDINATES
227+
x = (2.0 * self._coordinate[0]) / self.display_width - 1.0
228+
y = 1.0 - (2.0 * self._coordinate[1]) / self.display_height
229+
return _numpy.array([x, y], dtype=_numpy.float32)

cython_src/utility/perlin_noise.pyx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
1+
# cython: language_level=3
2+
13
from libc.math cimport floor
24
from libc.stdlib cimport rand, srand
35
from libc.time cimport time
46

7+
import cython
8+
59
cdef int PERMUTATION_SIZE = 512
610

711
# Declare that no exceptions will be propagated
812
cdef extern from "math.h":
9-
double floor(double) nogil
13+
double floor(double) noexcept nogil
1014

11-
cdef inline double fade(double t) nogil:
15+
cdef inline double fade(double t) noexcept nogil:
1216
"""
1317
🟩 **R** -
1418
"""
1519
return t * t * t * (t * (t * 6 - 15) + 10)
1620

17-
cdef inline double lerp(double t, double a, double b) nogil:
21+
cdef inline double lerp(double t, double a, double b) noexcept nogil:
1822
"""
1923
🟩 **R** -
2024
"""
2125
return a + t * (b - a)
2226

23-
cdef inline double grad1(int hash, double x) nogil:
27+
cdef inline double grad1(int hash, double x) noexcept nogil:
2428
"""
2529
🟩 **R** -
2630
"""
@@ -30,7 +34,7 @@ cdef inline double grad1(int hash, double x) nogil:
3034
grad = -grad # and a random sign for the gradient
3135
return grad * x # Multiply the gradient with the distance
3236

33-
cdef inline double grad2(int hash, double x, double y) nogil:
37+
cdef inline double grad2(int hash, double x, double y) noexcept nogil:
3438
"""
3539
🟩 **R** -
3640
"""
@@ -39,7 +43,7 @@ cdef inline double grad2(int hash, double x, double y) nogil:
3943
cdef double v = y if h < 4 else x # and compute the dot product with (x,y).
4044
return ((-u if h & 1 else u) + (-2.0 * v if h & 2 else 2.0 * v))
4145

42-
cdef inline double grad3(int hash, double x, double y, double z) nogil:
46+
cdef inline double grad3(int hash, double x, double y, double z) noexcept nogil:
4347
"""
4448
🟩 **R** -
4549
"""
@@ -64,7 +68,7 @@ cdef class PerlinNoise:
6468
self.octaves = octaves
6569
self.persistence = persistence
6670

67-
cdef void init_permutation(self, int seed):
71+
cdef void init_permutation(self, int seed) noexcept:
6872
"""
6973
🟩 **R** -
7074
"""
@@ -84,7 +88,9 @@ cdef class PerlinNoise:
8488
for i in range(256):
8589
self.p[256 + i] = self.p[i] = perm[i]
8690

87-
cdef double perlin1D(self, double x):
91+
@cython.boundscheck(False)
92+
@cython.wraparound(False)
93+
cdef inline double perlin1D(self, double x) noexcept:
8894
"""
8995
🟩 **R** -
9096
"""
@@ -102,7 +108,9 @@ cdef class PerlinNoise:
102108

103109
return lerp(u, grad1(self.p[A], x), grad1(self.p[B], x - 1))
104110

105-
cdef double perlin2D(self, double x, double y):
111+
@cython.boundscheck(False)
112+
@cython.wraparound(False)
113+
cdef inline double perlin2D(self, double x, double y) noexcept:
106114
"""
107115
🟩 **R** -
108116
"""
@@ -124,7 +132,9 @@ cdef class PerlinNoise:
124132
return lerp(v, lerp(u, grad2(self.p[A], x, y), grad2(self.p[B], x - 1, y)),
125133
lerp(u, grad2(self.p[A + 1], x, y - 1), grad2(self.p[B + 1], x - 1, y - 1)))
126134

127-
cdef double perlin3D(self, double x, double y, double z):
135+
@cython.boundscheck(False)
136+
@cython.wraparound(False)
137+
cdef inline double perlin3D(self, double x, double y, double z) noexcept:
128138
"""
129139
🟩 **R** -
130140
"""
@@ -155,7 +165,7 @@ cdef class PerlinNoise:
155165
lerp(v, lerp(u, grad3(self.p[AA + 1], x, y, z - 1), grad3(self.p[BA + 1], x - 1, y, z - 1)),
156166
lerp(u, grad3(self.p[AB + 1], x, y - 1, z - 1), grad3(self.p[BB + 1], x - 1, y - 1, z - 1))))
157167

158-
cpdef double fBM1D(self, double x):
168+
cpdef double fBM1D(self, double x) noexcept:
159169
"""
160170
🟩 **R** -
161171
"""
@@ -173,7 +183,7 @@ cdef class PerlinNoise:
173183

174184
return total / maxValue
175185

176-
cpdef double fBM2D(self, double x, double y):
186+
cpdef double fBM2D(self, double x, double y) noexcept:
177187
"""
178188
🟩 **R** -
179189
"""
@@ -191,7 +201,7 @@ cdef class PerlinNoise:
191201

192202
return total / maxValue
193203

194-
cpdef double fBM3D(self, double x, double y, double z):
204+
cpdef double fBM3D(self, double x, double y, double z) noexcept:
195205
"""
196206
🟩 **R** -
197207
"""

cython_src/utility/render_pipeline_utils.pyx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# cython: language_level=3
2+
13
import cython
24

35
from libc.string cimport memcpy
@@ -16,7 +18,7 @@ from pmma.python_src.utility.registry_utils import Registry as _Registry
1618

1719
@cython.boundscheck(False)
1820
@cython.wraparound(False)
19-
cdef inline cnp.ndarray[cnp.float32_t, ndim=1] repeat_array_cython(cnp.ndarray[cnp.float32_t, ndim=1] base, int N) noexcept:
21+
cdef inline cnp.ndarray[cnp.float32_t, ndim=1] repeat_array_cython(cnp.ndarray[cnp.float32_t, ndim=1] base, int N):
2022
cdef int base_size = base.shape[0]
2123
cdef cnp.ndarray[cnp.float32_t, ndim=1] result = np.empty(N * base_size, dtype=np.float32)
2224
cdef int i
@@ -49,7 +51,7 @@ cdef class RenderPipeline:
4951

5052
@cython.boundscheck(False) # compiler directive
5153
@cython.wraparound(False) # compiler directive
52-
cdef void internal_update(self, list shape_data, int total_data_points):
54+
cdef void internal_update(self, list shape_data, int total_data_points) noexcept:
5355
cdef cnp.float32_t[::1] pipeline_data = np.empty(total_data_points, dtype=np.float32)
5456
cdef cnp.float32_t[::1] colors, vertices, offsets
5557
cdef int index = 0

0 commit comments

Comments
 (0)