diff -r 8ff82697f2c3 -r 148b7c7ccaf9 src/array_list.c --- a/src/array_list.c Sat Jan 25 15:22:01 2025 +0100 +++ b/src/array_list.c Tue Jan 28 18:31:17 2025 +0100 @@ -856,32 +856,42 @@ } } -static ssize_t cx_arl_find_remove( +static size_t cx_arl_find_remove( struct cx_list_s *list, const void *elem, bool remove ) { + assert(list != NULL); assert(list->collection.cmpfunc != NULL); - assert(list->collection.size < SIZE_MAX / 2); + if (list->collection.size == 0) return 0; char *cur = ((const cx_array_list *) list)->data; - for (ssize_t i = 0; i < (ssize_t) list->collection.size; i++) { + // optimize with binary search, when sorted + if (list->collection.sorted) { + size_t i = cx_array_binary_search( + cur, + list->collection.size, + list->collection.elem_size, + elem, + list->collection.cmpfunc + ); + if (remove && i < list->collection.size) { + cx_arl_remove(list, i, 1, NULL); + } + return i; + } + + // fallback: linear search + for (size_t i = 0; i < list->collection.size; i++) { if (0 == list->collection.cmpfunc(elem, cur)) { if (remove) { - if (1 == cx_arl_remove(list, i, 1, NULL)) { - return i; - } else { - // should be unreachable - return -1; // LCOV_EXCL_LINE - } - } else { - return i; + cx_arl_remove(list, i, 1, NULL); } + return i; } cur += list->collection.elem_size; } - - return -1; + return list->collection.size; } static void cx_arl_sort(struct cx_list_s *list) {