Perform identity checking before equality checking for table keys

This commit is contained in:
K. Lange 2022-07-06 14:55:06 +09:00
parent c49a12effc
commit 388a649ec9
3 changed files with 23 additions and 1 deletions

View File

@ -180,6 +180,16 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b);
*/
extern int krk_valuesSame(KrkValue a, KrkValue b);
/**
* @brief Compare two values by identity, then by equality.
* @memberof KrkValue
*
* More efficient than just @c krk_valuesSame followed by @c krk_valuesEqual
*
* @return 1 if values represent the same object or value, 0 otherwise.
*/
extern int krk_valuesSameOrEqual(KrkValue a, KrkValue b);
extern KrkValue krk_parse_int(const char * start, size_t width, unsigned int base);
typedef union {

View File

@ -75,7 +75,7 @@ KrkTableEntry * krk_findEntry(KrkTableEntry * entries, size_t capacity, KrkValue
if (tombstone == entry) return tombstone;
if (tombstone == NULL) tombstone = entry;
}
} else if (krk_valuesEqual(entry->key, key)) {
} else if (krk_valuesSameOrEqual(entry->key, key)) {
return entry;
}
index = (index + 1) & (capacity-1);

View File

@ -148,6 +148,18 @@ int krk_valuesSame(KrkValue a, KrkValue b) {
return krk_valuesEqual(a,b) || (!krk_valuesEqual(a,a) && !krk_valuesEqual(b,b));
}
int krk_valuesSameOrEqual(KrkValue a, KrkValue b) {
/* We want to do this more efficiently than just calling one then the other. */
if (KRK_VAL_TYPE(a) == KRK_VAL_TYPE(b)) {
if (IS_OBJECT(a)) {
if (a == b) return 1;
return krk_valuesEqual(a,b);
}
return krk_valuesEqual(a,b) || (!krk_valuesEqual(a,a) && !krk_valuesEqual(b,b));
}
return krk_valuesEqual(a,b);
}
__attribute__((hot))
inline
int krk_valuesEqual(KrkValue a, KrkValue b) {