patch 9.0.1895: Vim9: finding object method/member is inefficient

Commit: 
https://github.com/vim/vim/commit/4d00b835c49ffc5c416b65ca466d6ad695cbd3d2
Author: Ernie Rael <err...@raelity.com>
Date:   Mon Sep 11 19:54:42 2023 +0200

    patch 9.0.1895: Vim9: finding object method/member is inefficient
    
    Problem:  Vim9: finding method/member is inefficient
    Solution: Use lookups
    
    closes: #13073
    
    Signed-off-by: Christian Brabandt <c...@256bit.org>
    Co-authored-by: Ernie Rael <err...@raelity.com>

diff --git a/src/version.c b/src/version.c
index d37d14721..c56ef4cea 100644
--- a/src/version.c
+++ b/src/version.c
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1895,
 /**/
     1894,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index 15d2b0913..ccc381838 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -1883,9 +1883,8 @@ class_object_index(
     if (*name_end == '(')
     {
        ufunc_T *fp;
-       int     m_idx;
 
-       fp = method_lookup(cl, rettv->v_type, name, len, &m_idx);
+       fp = method_lookup(cl, rettv->v_type, name, len, NULL);
        if (fp == NULL)
        {
            semsg(_(e_method_not_found_on_class_str_str), cl->class_name,
@@ -2022,8 +2021,7 @@ find_class_func(char_u **arg)
        goto fail_after_eval;
     len = fname_end - fname;
 
-    int m_idx;
-    fp = method_lookup(cl, tv.v_type, fname, len, &m_idx);
+    fp = method_lookup(cl, tv.v_type, fname, len, NULL);
 
 fail_after_eval:
     clear_tv(&tv);
@@ -2038,20 +2036,9 @@ fail_after_eval:
     int
 class_member_idx(class_T *cl, char_u *name, size_t namelen)
 {
-    for (int i = 0; i < cl->class_class_member_count; ++i)
-    {
-       ocmember_T *m = &cl->class_class_members[i];
-       if (namelen)
-       {
-           if (STRNCMP(name, m->ocm_name, namelen) == 0
-                   && m->ocm_name[namelen] == NUL)
-               return i;
-       }
-       else if (STRCMP(name, m->ocm_name) == 0)
-           return i;
-    }
-
-    return -1;
+    int idx;
+    class_member_lookup(cl, name, namelen, &idx);
+    return idx;
 }
 
 /*
@@ -2062,8 +2049,31 @@ class_member_idx(class_T *cl, char_u *name, size_t 
namelen)
     ocmember_T *
 class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
 {
-    *idx = class_member_idx(cl, name, namelen);
-    return *idx >= 0 ? &cl->class_class_members[*idx] : NULL;
+    ocmember_T *ret_m = NULL;
+    int                ret_idx = -1;
+    for (int i = 0; i < cl->class_class_member_count; ++i)
+    {
+       ocmember_T *m = &cl->class_class_members[i];
+       if (namelen)
+       {
+           if (STRNCMP(name, m->ocm_name, namelen) == 0
+                   && m->ocm_name[namelen] == NUL)
+           {
+               ret_m = m;
+               ret_idx = i;
+               break;
+           }
+       }
+       else if (STRCMP(name, m->ocm_name) == 0)
+       {
+           ret_m = m;
+           ret_idx = i;
+            break;
+       }
+    }
+    if (idx != NULL)
+       *idx = ret_idx;
+    return ret_m;
 }
 
 /*
@@ -2073,15 +2083,9 @@ class_member_lookup(class_T *cl, char_u *name, size_t 
namelen, int *idx)
     int
 class_method_idx(class_T *cl, char_u *name, size_t namelen)
 {
-    for (int i = 0; i < cl->class_class_function_count; ++i)
-    {
-       ufunc_T *fp = cl->class_class_functions[i];
-       char_u *ufname = (char_u *)fp->uf_name;
-       if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
-           return i;
-    }
-
-    return -1;
+    int idx;
+    class_method_lookup(cl, name, namelen, &idx);
+    return idx;
 }
 
 /*
@@ -2092,8 +2096,22 @@ class_method_idx(class_T *cl, char_u *name, size_t 
namelen)
     ufunc_T *
 class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
 {
-    *idx = class_method_idx(cl, name, namelen);
-    return *idx >= 0 ? cl->class_class_functions[*idx] : NULL;
+    ufunc_T    *ret_fp = NULL;
+    int                ret_idx = -1;
+    for (int i = 0; i < cl->class_class_function_count; ++i)
+    {
+       ufunc_T *fp = cl->class_class_functions[i];
+       char_u *ufname = (char_u *)fp->uf_name;
+       if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
+       {
+           ret_fp = fp;
+           ret_idx = i;
+           break;
+       }
+    }
+    if (idx != NULL)
+       *idx = ret_idx;
+    return ret_fp;
 }
 
 /*
@@ -2104,20 +2122,9 @@ class_method_lookup(class_T *cl, char_u *name, size_t 
namelen, int *idx)
     int
 object_member_idx(class_T *cl, char_u *name, size_t namelen)
 {
-    for (int i = 0; i < cl->class_obj_member_count; ++i)
-    {
-       ocmember_T *m = &cl->class_obj_members[i];
-       if (namelen)
-       {
-           if (STRNCMP(name, m->ocm_name, namelen) == 0
-                   && m->ocm_name[namelen] == NUL)
-           return i;
-       }
-       else if (STRCMP(name, m->ocm_name) == 0)
-           return i;
-    }
-
-    return -1;
+    int idx;
+    object_member_lookup(cl, name, namelen, &idx);
+    return idx;
 }
 
 /*
@@ -2128,8 +2135,31 @@ object_member_idx(class_T *cl, char_u *name, size_t 
namelen)
     ocmember_T *
 object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
 {
-    *idx = object_member_idx(cl, name, namelen);
-    return *idx >= 0 ? &cl->class_obj_members[*idx] : NULL;
+    ocmember_T *ret_m = NULL;
+    int                ret_idx = -1;
+    for (int i = 0; i < cl->class_obj_member_count; ++i)
+    {
+       ocmember_T  *m = &cl->class_obj_members[i];
+       if (namelen)
+       {
+           if (STRNCMP(name, m->ocm_name, namelen) == 0
+                   && m->ocm_name[namelen] == NUL)
+           {
+               ret_m = m;
+               ret_idx = i;
+               break;
+           }
+       }
+       else if (STRCMP(name, m->ocm_name) == 0)
+        {
+           ret_m = m;
+           ret_idx = i;
+            break;
+        }
+    }
+    if (idx != NULL)
+       *idx = ret_idx;
+    return ret_m;
 }
 
 /*
@@ -2139,17 +2169,9 @@ object_member_lookup(class_T *cl, char_u *name, size_t 
namelen, int *idx)
     int
 object_method_idx(class_T *cl, char_u *name, size_t namelen)
 {
-    for (int i = 0; i < cl->class_obj_method_count; ++i)
-    {
-       ufunc_T *fp = cl->class_obj_methods[i];
-       // Use a separate pointer to avoid that ASAN complains about
-       // uf_name[] only being 4 characters.
-       char_u *ufname = (char_u *)fp->uf_name;
-       if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
-           return i;
-    }
-
-    return -1;
+    int idx;
+    object_method_lookup(cl, name, namelen, &idx);
+    return idx;
 }
 
 /*
@@ -2160,8 +2182,24 @@ object_method_idx(class_T *cl, char_u *name, size_t 
namelen)
     ufunc_T *
 object_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
 {
-    *idx = object_method_idx(cl, name, namelen);
-    return *idx >= 0 ? cl->class_obj_methods[*idx] : NULL;
+    ufunc_T    *ret_fp = NULL;
+    int                ret_idx = -1;
+    for (int i = 0; i < cl->class_obj_method_count; ++i)
+    {
+       ufunc_T *fp = cl->class_obj_methods[i];
+       // Use a separate pointer to avoid that ASAN complains about
+       // uf_name[] only being 4 characters.
+       char_u *ufname = (char_u *)fp->uf_name;
+       if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
+       {
+           ret_fp = fp;
+           ret_idx = i;
+           break;
+       }
+    }
+    if (idx != NULL)
+       *idx = ret_idx;
+    return ret_fp;
 }
 
 /*
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 0315f4f7b..120a60627 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -394,10 +394,10 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, 
type_T *type)
 
     if (type->tt_type == VAR_OBJECT)
     {
-       int m_idx = object_member_idx(cl, name, len);
+        int m_idx;
+        ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
        if (m_idx >= 0)
        {
-           ocmember_T *m = &cl->class_obj_members[m_idx];
            if (*name == '_' && !inside_class(cctx, cl))
            {
                semsg(_(e_cannot_access_private_member_str), m->ocm_name);
diff --git a/src/vim9instr.c b/src/vim9instr.c
index dcbe897cd..ccec0bcc3 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1838,9 +1838,7 @@ generate_CALL(
                {
                    class_T *clp = mtype->tt_class;
                    char_u  *aname = ((char_u **)ufunc->uf_args.ga_data)[i];
-                   int     m_idx;
-                   ocmember_T *m = object_member_lookup(clp, aname, 0,
-                                                                       &m_idx);
+                   ocmember_T *m = object_member_lookup(clp, aname, 0, NULL);
                    if (m != NULL)
                        expected = m->ocm_type;
                }

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qflCe-007sLu-0D%40256bit.org.

Raspunde prin e-mail lui