Skip to content

Commit 109d05e

Browse files
authored
[mypyc] Implement list insert primitive (#9741)
Implements list insert primitive for improved performance. Related ticket: mypyc/mypyc#644
1 parent d1d999c commit 109d05e

File tree

5 files changed

+41
-0
lines changed

5 files changed

+41
-0
lines changed

mypyc/lib-rt/CPy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ bool CPyList_SetItem(PyObject *list, CPyTagged index, PyObject *value);
323323
PyObject *CPyList_PopLast(PyObject *obj);
324324
PyObject *CPyList_Pop(PyObject *obj, CPyTagged index);
325325
CPyTagged CPyList_Count(PyObject *obj, PyObject *value);
326+
int CPyList_Insert(PyObject *list, CPyTagged index, PyObject *value);
326327
PyObject *CPyList_Extend(PyObject *o1, PyObject *o2);
327328
PyObject *CPySequence_Multiply(PyObject *seq, CPyTagged t_size);
328329
PyObject *CPySequence_RMultiply(CPyTagged t_size, PyObject *seq);

mypyc/lib-rt/list_ops.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ CPyTagged CPyList_Count(PyObject *obj, PyObject *value)
108108
return list_count((PyListObject *)obj, value);
109109
}
110110

111+
int CPyList_Insert(PyObject *list, CPyTagged index, PyObject *value)
112+
{
113+
if (CPyTagged_CheckShort(index)) {
114+
Py_ssize_t n = CPyTagged_ShortAsSsize_t(index);
115+
return PyList_Insert(list, n, value);
116+
}
117+
return -1;
118+
}
119+
111120
PyObject *CPyList_Extend(PyObject *o1, PyObject *o2) {
112121
return _PyList_Extend((PyListObject *)o1, o2);
113122
}

mypyc/primitives/list_ops.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@
105105
c_function_name='CPyList_Count',
106106
error_kind=ERR_MAGIC)
107107

108+
# list.insert(index, obj)
109+
method_op(
110+
name='insert',
111+
arg_types=[list_rprimitive, int_rprimitive, object_rprimitive],
112+
return_type=c_int_rprimitive,
113+
c_function_name='CPyList_Insert',
114+
error_kind=ERR_NEG_INT)
115+
108116
# list * int
109117
binary_op(
110118
name='*',

mypyc/test-data/irbuild-lists.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,20 @@ L0:
233233
r2 = r1 >= 0 :: signed
234234
r3 = truncate r1: int32 to builtins.bool
235235
return r3
236+
237+
[case testListInsert]
238+
from typing import List
239+
def f(x: List[int], y: int) -> None:
240+
x.insert(0, y)
241+
[out]
242+
def f(x, y):
243+
x :: list
244+
y :: int
245+
r0 :: object
246+
r1 :: int32
247+
r2 :: bit
248+
L0:
249+
r0 = box(int, y)
250+
r1 = CPyList_Insert(x, 0, r0)
251+
r2 = r1 >= 0 :: signed
252+
return 1

mypyc/test-data/run-lists.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ pop(l, -2)
103103
assert l == [1, 3]
104104
assert count(l, 1) == 1
105105
assert count(l, 2) == 0
106+
l.insert(0, 0)
107+
assert l == [0, 1, 3]
108+
l.insert(2, 2)
109+
assert l == [0, 1, 2, 3]
110+
l.insert(4, 4)
111+
assert l == [0, 1, 2, 3, 4]
106112

107113
[case testListOfUserDefinedClass]
108114
class C:

0 commit comments

Comments
 (0)