@@ -98,13 +98,33 @@ STATIC void mp_map_rehash(mp_map_t *map) {
9898// MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour:
9999// - returns NULL if not found, else the slot if was found in with key null and value non-null
100100mp_map_elem_t * mp_map_lookup (mp_map_t * map , mp_obj_t index , mp_map_lookup_kind_t lookup_kind ) {
101+
102+ // Work out if we can compare just pointers
103+ bool compare_only_ptrs = map -> all_keys_are_qstrs ;
104+ if (compare_only_ptrs ) {
105+ if (MP_OBJ_IS_QSTR (index )) {
106+ // Index is a qstr, so can just do ptr comparison.
107+ } else if (MP_OBJ_IS_TYPE (index , & mp_type_str )) {
108+ // Index is a non-interned string.
109+ // We can either intern the string, or force a full equality comparison.
110+ // We chose the latter, since interning costs time and potentially RAM,
111+ // and it won't necessarily benefit subsequent calls because these calls
112+ // most likely won't pass the newly-interned string.
113+ compare_only_ptrs = false;
114+ } else if (!(lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND )) {
115+ // If we are not adding, then we can return straight away a failed
116+ // lookup because we know that the index will never be found.
117+ return NULL ;
118+ }
119+ }
120+
101121 // if the map is a fixed array then we must do a brute force linear search
102122 if (map -> table_is_fixed_array ) {
103123 if (lookup_kind != MP_MAP_LOOKUP ) {
104124 return NULL ;
105125 }
106126 for (mp_map_elem_t * elem = & map -> table [0 ], * top = & map -> table [map -> used ]; elem < top ; elem ++ ) {
107- if (elem -> key == index || (!map -> all_keys_are_qstrs && mp_obj_equal (elem -> key , index ))) {
127+ if (elem -> key == index || (!compare_only_ptrs && mp_obj_equal (elem -> key , index ))) {
108128 return elem ;
109129 }
110130 }
@@ -148,7 +168,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
148168 if (avail_slot == NULL ) {
149169 avail_slot = slot ;
150170 }
151- } else if (slot -> key == index || (!map -> all_keys_are_qstrs && mp_obj_equal (slot -> key , index ))) {
171+ } else if (slot -> key == index || (!compare_only_ptrs && mp_obj_equal (slot -> key , index ))) {
152172 // found index
153173 // Note: CPython does not replace the index; try x={True:'true'};x[1]='one';x
154174 if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND ) {
0 commit comments