Skip to content

Commit 7b0beba

Browse files
authored
Merge pull request #2784 from itzpr3d4t0r/optimize_rect_unionall
Optimized ( Rect/Frect ) unionall()/unionall_ip()
2 parents 7a6d4a7 + 92f27a3 commit 7b0beba

File tree

2 files changed

+97
-54
lines changed

2 files changed

+97
-54
lines changed

src_c/rect.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,7 @@ static struct PyMethodDef pg_rect_methods[] = {
469469
{"update", (PyCFunction)pg_rect_update, METH_FASTCALL, DOC_RECT_UPDATE},
470470
{"inflate", (PyCFunction)pg_rect_inflate, METH_VARARGS, DOC_RECT_INFLATE},
471471
{"union", (PyCFunction)pg_rect_union, METH_FASTCALL, DOC_RECT_UNION},
472-
{"unionall", (PyCFunction)pg_rect_unionall, METH_VARARGS,
473-
DOC_RECT_UNIONALL},
472+
{"unionall", (PyCFunction)pg_rect_unionall, METH_O, DOC_RECT_UNIONALL},
474473
{"move_ip", (PyCFunction)pg_rect_move_ip, METH_FASTCALL, DOC_RECT_MOVEIP},
475474
{"move_to", (PyCFunction)pg_rect_move_to, METH_FASTCALL | METH_KEYWORDS,
476475
DOC_RECT_MOVETO},
@@ -482,7 +481,7 @@ static struct PyMethodDef pg_rect_methods[] = {
482481
METH_VARARGS | METH_KEYWORDS, DOC_RECT_SCALEBYIP},
483482
{"union_ip", (PyCFunction)pg_rect_union_ip, METH_FASTCALL,
484483
DOC_RECT_UNIONIP},
485-
{"unionall_ip", (PyCFunction)pg_rect_unionall_ip, METH_VARARGS,
484+
{"unionall_ip", (PyCFunction)pg_rect_unionall_ip, METH_O,
486485
DOC_RECT_UNIONALLIP},
487486
{"collidepoint", (PyCFunction)pg_rect_collidepoint, METH_FASTCALL,
488487
DOC_RECT_COLLIDEPOINT},
@@ -521,8 +520,7 @@ static struct PyMethodDef pg_frect_methods[] = {
521520
{"update", (PyCFunction)pg_frect_update, METH_FASTCALL, DOC_RECT_UPDATE},
522521
{"inflate", (PyCFunction)pg_frect_inflate, METH_VARARGS, DOC_RECT_INFLATE},
523522
{"union", (PyCFunction)pg_frect_union, METH_FASTCALL, DOC_RECT_UNION},
524-
{"unionall", (PyCFunction)pg_frect_unionall, METH_VARARGS,
525-
DOC_RECT_UNIONALL},
523+
{"unionall", (PyCFunction)pg_frect_unionall, METH_O, DOC_RECT_UNIONALL},
526524
{"move_ip", (PyCFunction)pg_frect_move_ip, METH_FASTCALL, DOC_RECT_MOVEIP},
527525
{"move_to", (PyCFunction)pg_frect_move_to, METH_FASTCALL | METH_KEYWORDS,
528526
DOC_RECT_MOVETO},
@@ -534,7 +532,7 @@ static struct PyMethodDef pg_frect_methods[] = {
534532
METH_VARARGS | METH_KEYWORDS, DOC_RECT_SCALEBYIP},
535533
{"union_ip", (PyCFunction)pg_frect_union_ip, METH_FASTCALL,
536534
DOC_RECT_UNIONIP},
537-
{"unionall_ip", (PyCFunction)pg_frect_unionall_ip, METH_VARARGS,
535+
{"unionall_ip", (PyCFunction)pg_frect_unionall_ip, METH_O,
538536
DOC_RECT_UNIONALLIP},
539537
{"collidepoint", (PyCFunction)pg_frect_collidepoint, METH_FASTCALL,
540538
DOC_RECT_COLLIDEPOINT},

src_c/rect_impl.h

Lines changed: 93 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,17 +1164,14 @@ RectExport_unionIp(RectObject *self, PyObject *const *args, Py_ssize_t nargs)
11641164
}
11651165

11661166
static PyObject *
1167-
RectExport_unionall(RectObject *self, PyObject *args)
1167+
RectExport_unionall(RectObject *self, PyObject *arg)
11681168
{
11691169
InnerRect *argrect, temp;
11701170
Py_ssize_t loop, size;
1171-
PyObject *list, *obj;
1171+
PyObject *obj;
11721172
PrimitiveType t, l, b, r;
11731173

1174-
if (!PyArg_ParseTuple(args, "O", &list)) {
1175-
return NULL;
1176-
}
1177-
if (!PySequence_Check(list)) {
1174+
if (!PySequence_Check(arg)) {
11781175
return RAISE(PyExc_TypeError,
11791176
"Argument must be a sequence of rectstyle objects.");
11801177
}
@@ -1183,44 +1180,67 @@ RectExport_unionall(RectObject *self, PyObject *args)
11831180
t = self->r.y;
11841181
r = self->r.x + self->r.w;
11851182
b = self->r.y + self->r.h;
1186-
size = PySequence_Length(list); /*warning, size could be -1 on error?*/
1187-
if (size < 1) {
1188-
if (size < 0) {
1189-
/*Error.*/
1190-
return NULL;
1183+
1184+
if (pgSequenceFast_Check(arg)) {
1185+
PyObject **items = PySequence_Fast_ITEMS(arg);
1186+
size = PySequence_Fast_GET_SIZE(arg);
1187+
1188+
if (size < 1) {
1189+
/*Empty arg: nothing to be done.*/
1190+
return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t);
1191+
}
1192+
1193+
for (loop = 0; loop < size; ++loop) {
1194+
if (!(argrect = RectFromObject(items[loop], &temp))) {
1195+
return RAISE(
1196+
PyExc_TypeError,
1197+
"Argument must be a sequence of rectstyle objects.");
1198+
}
1199+
l = MIN(l, argrect->x);
1200+
t = MIN(t, argrect->y);
1201+
r = MAX(r, argrect->x + argrect->w);
1202+
b = MAX(b, argrect->y + argrect->h);
11911203
}
1192-
/*Empty list: nothing to be done.*/
1193-
return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t);
11941204
}
1205+
else {
1206+
size = PySequence_Length(arg); /*warning, size could be -1 on error?*/
1207+
if (size < 1) {
1208+
if (size < 0) {
1209+
/*Error.*/
1210+
return NULL;
1211+
}
1212+
/*Empty arg: nothing to be done.*/
1213+
return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t);
1214+
}
11951215

1196-
for (loop = 0; loop < size; ++loop) {
1197-
obj = PySequence_GetItem(list, loop);
1198-
if (!obj || !(argrect = RectFromObject(obj, &temp))) {
1199-
Py_XDECREF(obj);
1200-
return RAISE(PyExc_TypeError,
1201-
"Argument must be a sequence of rectstyle objects.");
1216+
for (loop = 0; loop < size; ++loop) {
1217+
obj = PySequence_ITEM(arg, loop);
1218+
if (!obj || !(argrect = RectFromObject(obj, &temp))) {
1219+
Py_XDECREF(obj);
1220+
return RAISE(
1221+
PyExc_TypeError,
1222+
"Argument must be a sequence of rectstyle objects.");
1223+
}
1224+
l = MIN(l, argrect->x);
1225+
t = MIN(t, argrect->y);
1226+
r = MAX(r, argrect->x + argrect->w);
1227+
b = MAX(b, argrect->y + argrect->h);
1228+
Py_DECREF(obj);
12021229
}
1203-
l = MIN(l, argrect->x);
1204-
t = MIN(t, argrect->y);
1205-
r = MAX(r, argrect->x + argrect->w);
1206-
b = MAX(b, argrect->y + argrect->h);
1207-
Py_DECREF(obj);
12081230
}
1231+
12091232
return RectExport_subtypeNew4(Py_TYPE(self), l, t, r - l, b - t);
12101233
}
12111234

12121235
static PyObject *
1213-
RectExport_unionallIp(RectObject *self, PyObject *args)
1236+
RectExport_unionallIp(RectObject *self, PyObject *arg)
12141237
{
12151238
InnerRect *argrect, temp;
12161239
Py_ssize_t loop, size;
1217-
PyObject *list, *obj;
1240+
PyObject *obj;
12181241
PrimitiveType t, l, b, r;
12191242

1220-
if (!PyArg_ParseTuple(args, "O", &list)) {
1221-
return NULL;
1222-
}
1223-
if (!PySequence_Check(list)) {
1243+
if (!PySequence_Check(arg)) {
12241244
return RAISE(PyExc_TypeError,
12251245
"Argument must be a sequence of rectstyle objects.");
12261246
}
@@ -1230,34 +1250,59 @@ RectExport_unionallIp(RectObject *self, PyObject *args)
12301250
r = self->r.x + self->r.w;
12311251
b = self->r.y + self->r.h;
12321252

1233-
size = PySequence_Length(list); /*warning, size could be -1 on error?*/
1234-
if (size < 1) {
1235-
if (size < 0) {
1236-
/*Error.*/
1237-
return NULL;
1253+
if (pgSequenceFast_Check(arg)) {
1254+
PyObject **items = PySequence_Fast_ITEMS(arg);
1255+
size = PySequence_Fast_GET_SIZE(arg);
1256+
1257+
if (size < 1) {
1258+
/*Empty arg: nothing to be done.*/
1259+
Py_RETURN_NONE;
1260+
}
1261+
1262+
for (loop = 0; loop < size; ++loop) {
1263+
if (!(argrect = RectFromObject(items[loop], &temp))) {
1264+
return RAISE(
1265+
PyExc_TypeError,
1266+
"Argument must be a sequence of rectstyle objects.");
1267+
}
1268+
l = MIN(l, argrect->x);
1269+
t = MIN(t, argrect->y);
1270+
r = MAX(r, argrect->x + argrect->w);
1271+
b = MAX(b, argrect->y + argrect->h);
12381272
}
1239-
/*Empty list: nothing to be done.*/
1240-
Py_RETURN_NONE;
12411273
}
1274+
else {
1275+
size = PySequence_Length(arg); /*warning, size could be -1 on error?*/
1276+
if (size < 1) {
1277+
if (size < 0) {
1278+
/*Error.*/
1279+
return NULL;
1280+
}
1281+
/*Empty arg: nothing to be done.*/
1282+
Py_RETURN_NONE;
1283+
}
12421284

1243-
for (loop = 0; loop < size; ++loop) {
1244-
obj = PySequence_GetItem(list, loop);
1245-
if (!obj || !(argrect = RectFromObject(obj, &temp))) {
1246-
Py_XDECREF(obj);
1247-
return RAISE(PyExc_TypeError,
1248-
"Argument must be a sequence of rectstyle objects.");
1285+
for (loop = 0; loop < size; ++loop) {
1286+
obj = PySequence_ITEM(arg, loop);
1287+
if (!obj || !(argrect = RectFromObject(obj, &temp))) {
1288+
Py_XDECREF(obj);
1289+
return RAISE(
1290+
PyExc_TypeError,
1291+
"Argument must be a sequence of rectstyle objects.");
1292+
}
1293+
l = MIN(l, argrect->x);
1294+
t = MIN(t, argrect->y);
1295+
r = MAX(r, argrect->x + argrect->w);
1296+
b = MAX(b, argrect->y + argrect->h);
1297+
Py_DECREF(obj);
12491298
}
1250-
l = MIN(l, argrect->x);
1251-
t = MIN(t, argrect->y);
1252-
r = MAX(r, argrect->x + argrect->w);
1253-
b = MAX(b, argrect->y + argrect->h);
1254-
Py_DECREF(obj);
12551299
}
12561300

12571301
self->r.x = l;
12581302
self->r.y = t;
12591303
self->r.w = r - l;
12601304
self->r.h = b - t;
1305+
12611306
Py_RETURN_NONE;
12621307
}
12631308

0 commit comments

Comments
 (0)