Skip to content

Commit 4941f85

Browse files
committed
Optimize list conversion to avoid temporary array allocation
Build Erlang lists directly using enif_make_list_cell instead of allocating a temporary array and calling enif_make_list_from_array. The optimization iterates the Python list in reverse and prepends each element to build the list. This is O(1) per element and avoids the overhead of allocating/freeing a temporary ERL_NIF_TERM array.
1 parent 7d61857 commit 4941f85

1 file changed

Lines changed: 10 additions & 13 deletions

File tree

c_src/py_convert.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -173,23 +173,20 @@ static ERL_NIF_TERM py_to_term(ErlNifEnv *env, PyObject *obj) {
173173
return bin;
174174
}
175175

176-
/* Handle lists */
176+
/*
177+
* Handle lists - build directly without temporary array allocation.
178+
* We iterate in reverse and prepend each element, which is O(1) per element
179+
* and avoids the overhead of allocating/freeing a temporary array.
180+
*/
177181
if (PyList_Check(obj)) {
178182
Py_ssize_t len = PyList_Size(obj);
179-
if (len == 0) {
180-
return enif_make_list(env, 0);
181-
}
182-
ERL_NIF_TERM *items = enif_alloc(sizeof(ERL_NIF_TERM) * len);
183-
if (items == NULL) {
184-
return ATOM_ERROR;
185-
}
186-
for (Py_ssize_t i = 0; i < len; i++) {
183+
ERL_NIF_TERM list = enif_make_list(env, 0); /* Start with empty list */
184+
for (Py_ssize_t i = len - 1; i >= 0; i--) {
187185
PyObject *item = PyList_GetItem(obj, i); /* Borrowed ref */
188-
items[i] = py_to_term(env, item);
186+
ERL_NIF_TERM term = py_to_term(env, item);
187+
list = enif_make_list_cell(env, term, list);
189188
}
190-
ERL_NIF_TERM result = enif_make_list_from_array(env, items, len);
191-
enif_free(items);
192-
return result;
189+
return list;
193190
}
194191

195192
/*

0 commit comments

Comments
 (0)