Skip to content

Commit 99fb67b

Browse files
optimize for sets
1 parent 3b04c79 commit 99fb67b

File tree

5 files changed

+33
-13
lines changed

5 files changed

+33
-13
lines changed

Include/internal/pycore_opcode_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ extern "C" {
7474
#define CONSTANT_BUILTIN_ALL 3
7575
#define CONSTANT_BUILTIN_ANY 4
7676
#define CONSTANT_BUILTIN_LIST 5
77-
#define NUM_COMMON_CONSTANTS 6
77+
#define CONSTANT_BUILTIN_SET 6
78+
#define NUM_COMMON_CONSTANTS 7
7879

7980
/* Values used in the oparg for RESUME */
8081
#define RESUME_AT_FUNC_START 0

Lib/opcode.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()
4141
_special_method_names = _opcode.get_special_method_names()
4242
_common_constants = [builtins.AssertionError, builtins.NotImplementedError,
43-
builtins.tuple, builtins.all, builtins.any, builtins.list]
43+
builtins.tuple, builtins.all, builtins.any, builtins.list,
44+
builtins.set]
4445
_nb_ops = _opcode.get_nb_ops()
4546

4647
hascompare = [opmap["COMPARE_OP"]]

Lib/test/test_builtin.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def test_any(self):
246246
S = [10, 20, 30]
247247
self.assertEqual(any(x > 42 for x in S), False)
248248

249-
def test_all_any_tuple_list_optimization(self):
249+
def test_all_any_tuple_list_set_optimization(self):
250250
def f_all():
251251
return all(x-2 for x in [1,2,3])
252252

@@ -259,7 +259,10 @@ def f_tuple():
259259
def f_list():
260260
return list(2*x for x in [1,2,3])
261261

262-
funcs = [f_all, f_any, f_tuple, f_list]
262+
def f_set():
263+
return set(2*x for x in [1,2,3])
264+
265+
funcs = [f_all, f_any, f_tuple, f_list, f_set]
263266

264267
for f in funcs:
265268
# check that generator code object is not duplicated
@@ -269,33 +272,35 @@ def f_list():
269272

270273
# check the overriding the builtins works
271274

272-
global all, any, tuple, list
273-
saved = all, any, tuple, list
275+
global all, any, tuple, list, set
276+
saved = all, any, tuple, list, set
274277
try:
275278
all = lambda x : "all"
276279
any = lambda x : "any"
277280
tuple = lambda x : "tuple"
278281
list = lambda x : "list"
282+
set = lambda x : "set"
279283

280284
overridden_outputs = [f() for f in funcs]
281285
finally:
282-
all, any, tuple, list = saved
286+
all, any, tuple, list, set = saved
283287

284-
self.assertEqual(overridden_outputs, ['all', 'any', 'tuple', 'list'])
288+
self.assertEqual(overridden_outputs, ['all', 'any', 'tuple', 'list', 'set'])
285289
# Now repeat, overriding the builtins module as well
286-
saved = all, any, tuple, list
290+
saved = all, any, tuple, list, set
287291
try:
288292
builtins.all = all = lambda x : "all"
289293
builtins.any = any = lambda x : "any"
290294
builtins.tuple = tuple = lambda x : "tuple"
291295
builtins.list = list = lambda x : "list"
296+
builtins.set = set = lambda x : "set"
292297

293298
overridden_outputs = [f() for f in funcs]
294299
finally:
295-
all, any, tuple, list = saved
296-
builtins.all, builtins.any, builtins.tuple, builtins.list = saved
300+
all, any, tuple, list, set = saved
301+
builtins.all, builtins.any, builtins.tuple, builtins.list, builtins.set = saved
297302

298-
self.assertEqual(overridden_outputs, ['all', 'any', 'tuple', 'list'])
303+
self.assertEqual(overridden_outputs, ['all', 'any', 'tuple', 'list', 'set'])
299304

300305
def test_ascii(self):
301306
self.assertEqual(ascii(''), '\'\'')

Python/codegen.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3895,6 +3895,9 @@ maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
38953895
else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "list")) {
38963896
const_oparg = CONSTANT_BUILTIN_LIST;
38973897
}
3898+
else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "set")) {
3899+
const_oparg = CONSTANT_BUILTIN_SET;
3900+
}
38983901
if (const_oparg != -1) {
38993902
ADDOP_I(c, loc, COPY, 1); // the function
39003903
ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, const_oparg);
@@ -3904,6 +3907,8 @@ maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
39043907

39053908
if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
39063909
ADDOP_I(c, loc, BUILD_LIST, 0);
3910+
} else if (const_oparg == CONSTANT_BUILTIN_SET) {
3911+
ADDOP_I(c, loc, BUILD_SET, 0);
39073912
}
39083913
expr_ty generator_exp = asdl_seq_GET(args, 0);
39093914
VISIT(c, expr, generator_exp);
@@ -3917,14 +3922,19 @@ maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
39173922
if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
39183923
ADDOP_I(c, loc, LIST_APPEND, 3);
39193924
ADDOP_JUMP(c, loc, JUMP, loop);
3925+
} else if (const_oparg == CONSTANT_BUILTIN_SET) {
3926+
ADDOP_I(c, loc, SET_ADD, 3);
3927+
ADDOP_JUMP(c, loc, JUMP, loop);
39203928
}
39213929
else {
39223930
ADDOP(c, loc, TO_BOOL);
39233931
ADDOP_JUMP(c, loc, continue_jump_opcode, loop);
39243932
}
39253933

39263934
ADDOP(c, NO_LOCATION, POP_ITER);
3927-
if (const_oparg != CONSTANT_BUILTIN_TUPLE && const_oparg != CONSTANT_BUILTIN_LIST) {
3935+
if (const_oparg != CONSTANT_BUILTIN_TUPLE &&
3936+
const_oparg != CONSTANT_BUILTIN_LIST &&
3937+
const_oparg != CONSTANT_BUILTIN_SET) {
39283938
ADDOP_LOAD_CONST(c, loc, initial_res == Py_True ? Py_False : Py_True);
39293939
}
39303940
ADDOP_JUMP(c, loc, JUMP, end);
@@ -3936,6 +3946,8 @@ maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
39363946
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
39373947
} else if (const_oparg == CONSTANT_BUILTIN_LIST) {
39383948
// result is already a list
3949+
} else if (const_oparg == CONSTANT_BUILTIN_SET) {
3950+
// result is already a set
39393951
}
39403952
else {
39413953
ADDOP_LOAD_CONST(c, loc, initial_res);

Python/pylifecycle.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ pycore_init_builtins(PyThreadState *tstate)
830830
interp->common_consts[CONSTANT_BUILTIN_ALL] = all;
831831
interp->common_consts[CONSTANT_BUILTIN_ANY] = any;
832832
interp->common_consts[CONSTANT_BUILTIN_LIST] = (PyObject*)&PyList_Type;
833+
interp->common_consts[CONSTANT_BUILTIN_SET] = (PyObject*)&PySet_Type;
833834

834835
for (int i=0; i < NUM_COMMON_CONSTANTS; i++) {
835836
assert(interp->common_consts[i] != NULL);

0 commit comments

Comments
 (0)