Przeglądaj źródła

improve `lower_bound`

blueloveTH 1 rok temu
rodzic
commit
c6185c3d9c

+ 7 - 2
include/pocketpy/common/algorithm.h

@@ -12,7 +12,7 @@ extern "C" {
     do {                                                                                           \
         T* __first = ptr;                                                                          \
         int __len = count;                                                                         \
-        while(__len != 0) {                                                                        \
+        while(__len > 8) {                                                                         \
             int __l2 = __len >> 1;                                                                 \
             T* __m = __first + __l2;                                                               \
             if(less((*__m), (key))) {                                                              \
@@ -22,6 +22,10 @@ extern "C" {
                 __len = __l2;                                                                      \
             }                                                                                      \
         }                                                                                          \
+        while(__len && less(*__first, (key))) {                                                    \
+            ++__first;                                                                             \
+            --__len;                                                                               \
+        }                                                                                          \
         *(out_index) = __first - (T*)(ptr);                                                        \
     } while(0)
 
@@ -30,7 +34,8 @@ extern "C" {
  * @param ptr Pointer to the first element of the array.
  * @param count Number of elements in the array.
  * @param elem_size Size of each element in the array.
- * @param cmp Comparison function that takes two elements and returns an integer similar to `strcmp`.
+ * @param cmp Comparison function that takes two elements and returns an integer similar to
+ * `strcmp`.
  */
 void c11__stable_sort(void* ptr,
                       int count,

+ 5 - 13
include/pocketpy/xmacros/smallmap.h

@@ -86,19 +86,11 @@ void METHOD(set)(NAME* self, K key, V value) {
 }
 
 V* METHOD(try_get)(const NAME* self, K key) {
-    // use `bsearch` which is faster than `lower_bound`
-    int low = 0;
-    int high = self->count - 1;
-    KV* a = self->data;
-    while(low <= high){
-        int mid = (low + high) / 2;
-        if(equal(a[mid].key, key)){
-            return &a[mid].value;
-        } else if(less(a[mid].key, key)){
-            low = mid + 1;
-        } else {
-            high = mid - 1;
-        }
+    int index;
+    c11__lower_bound(KV, self->data, self->count, key, partial_less, &index);
+    if(index != self->count){
+        KV* it = c11__at(KV, self, index);
+        if(equal(it->key, key)) return &it->value;
     }
     return NULL;
 }