From 388a649ec96d6a68ec38ca1e2c7a9d82a75ba854 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Wed, 6 Jul 2022 14:55:06 +0900 Subject: [PATCH] Perform identity checking before equality checking for table keys --- src/kuroko/value.h | 10 ++++++++++ src/table.c | 2 +- src/value.c | 12 ++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/kuroko/value.h b/src/kuroko/value.h index 830f7bb..0120e60 100644 --- a/src/kuroko/value.h +++ b/src/kuroko/value.h @@ -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 { diff --git a/src/table.c b/src/table.c index 08976b8..2375e34 100644 --- a/src/table.c +++ b/src/table.c @@ -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); diff --git a/src/value.c b/src/value.c index 20441af..50a82d4 100644 --- a/src/value.c +++ b/src/value.c @@ -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) {