diff options
| author | Mattias EngdegÄrd | 2026-02-24 12:19:22 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2026-02-24 12:49:53 +0100 |
| commit | a84530ac2ed7b5c045176979002e635c9bdd462b (patch) | |
| tree | b777c2a7dfaa282ef8771d2ac6672c007efca94f /src | |
| parent | 2505af27c6aa97fdc2418fcaf0ff5047707c761f (diff) | |
| download | emacs-a84530ac2ed7b5c045176979002e635c9bdd462b.tar.gz emacs-a84530ac2ed7b5c045176979002e635c9bdd462b.zip | |
Speed up 'equal'-comparison of vectorlike objects
* src/fns.c (internal_equal_1): Switch on the vectorlike type instead of
using a sequence of type predicates.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fns.c | 73 |
1 files changed, 35 insertions, 38 deletions
| @@ -2940,12 +2940,12 @@ internal_equal_1 (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2940 | if (ASIZE (o2) != size) | 2940 | if (ASIZE (o2) != size) |
| 2941 | return false; | 2941 | return false; |
| 2942 | 2942 | ||
| 2943 | /* Compare bignums, overlays, markers, boolvectors, and | 2943 | switch (PSEUDOVECTOR_TYPE (XVECTOR (o1))) |
| 2944 | symbols with position specially, by comparing their values. */ | ||
| 2945 | if (BIGNUMP (o1)) | ||
| 2946 | return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; | ||
| 2947 | if (OVERLAYP (o1)) | ||
| 2948 | { | 2944 | { |
| 2945 | case PVEC_BIGNUM: | ||
| 2946 | return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; | ||
| 2947 | |||
| 2948 | case PVEC_OVERLAY: | ||
| 2949 | if (OVERLAY_BUFFER (o1) != OVERLAY_BUFFER (o2) | 2949 | if (OVERLAY_BUFFER (o1) != OVERLAY_BUFFER (o2) |
| 2950 | || OVERLAY_START (o1) != OVERLAY_START (o2) | 2950 | || OVERLAY_START (o1) != OVERLAY_START (o2) |
| 2951 | || OVERLAY_END (o1) != OVERLAY_END (o2)) | 2951 | || OVERLAY_END (o1) != OVERLAY_END (o2)) |
| @@ -2954,53 +2954,50 @@ internal_equal_1 (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2954 | o2 = XOVERLAY (o2)->plist; | 2954 | o2 = XOVERLAY (o2)->plist; |
| 2955 | depth++; | 2955 | depth++; |
| 2956 | goto tail_recurse; | 2956 | goto tail_recurse; |
| 2957 | } | 2957 | |
| 2958 | if (MARKERP (o1)) | 2958 | case PVEC_MARKER: |
| 2959 | { | ||
| 2960 | return (XMARKER (o1)->buffer == XMARKER (o2)->buffer | 2959 | return (XMARKER (o1)->buffer == XMARKER (o2)->buffer |
| 2961 | && (XMARKER (o1)->buffer == 0 | 2960 | && (XMARKER (o1)->buffer == 0 |
| 2962 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); | 2961 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); |
| 2963 | } | 2962 | |
| 2964 | if (BOOL_VECTOR_P (o1)) | 2963 | case PVEC_BOOL_VECTOR: |
| 2965 | { | 2964 | { |
| 2966 | EMACS_INT size = bool_vector_size (o1); | 2965 | EMACS_INT size = bool_vector_size (o1); |
| 2967 | return (size == bool_vector_size (o2) | 2966 | return (size == bool_vector_size (o2) |
| 2968 | && !memcmp (bool_vector_data (o1), bool_vector_data (o2), | 2967 | && !memcmp (bool_vector_data (o1), bool_vector_data (o2), |
| 2969 | bool_vector_bytes (size))); | 2968 | bool_vector_bytes (size))); |
| 2970 | } | 2969 | } |
| 2971 | 2970 | ||
| 2972 | #ifdef HAVE_TREE_SITTER | 2971 | #ifdef HAVE_TREE_SITTER |
| 2973 | if (TS_NODEP (o1)) | 2972 | case PVEC_TS_NODE: |
| 2974 | return treesit_node_eq (o1, o2); | 2973 | return treesit_node_eq (o1, o2); |
| 2975 | #endif | 2974 | #endif |
| 2976 | if (SYMBOL_WITH_POS_P (o1)) | 2975 | case PVEC_SYMBOL_WITH_POS: |
| 2977 | { | ||
| 2978 | eassert (!symbols_with_pos_enabled); | 2976 | eassert (!symbols_with_pos_enabled); |
| 2979 | return (BASE_EQ (XSYMBOL_WITH_POS_SYM (o1), | 2977 | return (BASE_EQ (XSYMBOL_WITH_POS_SYM (o1), |
| 2980 | XSYMBOL_WITH_POS_SYM (o2)) | 2978 | XSYMBOL_WITH_POS_SYM (o2)) |
| 2981 | && BASE_EQ (XSYMBOL_WITH_POS_POS (o1), | 2979 | && BASE_EQ (XSYMBOL_WITH_POS_POS (o1), |
| 2982 | XSYMBOL_WITH_POS_POS (o2))); | 2980 | XSYMBOL_WITH_POS_POS (o2))); |
| 2983 | } | ||
| 2984 | 2981 | ||
| 2985 | /* Aside from them, only true vectors, char-tables, compiled | 2982 | /* Compare these element-wise. */ |
| 2986 | functions, and fonts (font-spec, font-entity, font-object) | 2983 | case PVEC_CLOSURE: |
| 2987 | are sensible to compare, so eliminate the others now. */ | 2984 | case PVEC_CHAR_TABLE: |
| 2988 | if (size & PSEUDOVECTOR_FLAG) | 2985 | case PVEC_SUB_CHAR_TABLE: |
| 2989 | { | 2986 | case PVEC_RECORD: |
| 2990 | if (((size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS) | 2987 | case PVEC_FONT: |
| 2991 | < PVEC_CLOSURE) | ||
| 2992 | return false; | ||
| 2993 | size &= PSEUDOVECTOR_SIZE_MASK; | 2988 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 2989 | FALLTHROUGH; | ||
| 2990 | |||
| 2991 | case PVEC_NORMAL_VECTOR: | ||
| 2992 | for (ptrdiff_t i = 0; i < size; i++) | ||
| 2993 | if (!internal_equal_1 (AREF (o1, i), AREF (o2, i), | ||
| 2994 | equal_kind, depth + 1, ht)) | ||
| 2995 | return false; | ||
| 2996 | return true; | ||
| 2997 | |||
| 2998 | default: | ||
| 2999 | return false; | ||
| 2994 | } | 3000 | } |
| 2995 | for (ptrdiff_t i = 0; i < size; i++) | ||
| 2996 | { | ||
| 2997 | Lisp_Object v1, v2; | ||
| 2998 | v1 = AREF (o1, i); | ||
| 2999 | v2 = AREF (o2, i); | ||
| 3000 | if (!internal_equal_1 (v1, v2, equal_kind, depth + 1, ht)) | ||
| 3001 | return false; | ||
| 3002 | } | ||
| 3003 | return true; | ||
| 3004 | } | 3001 | } |
| 3005 | break; | 3002 | break; |
| 3006 | 3003 | ||