From 32ba2b516066688ff56e6d62a7ff4a01c88f5700 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 21 Dec 2010 22:11:40 -0500
Subject: [PATCH] Use memcmp() rather than strncmp() when shorter string length
 is known.

It appears that this will be faster for all but the shortest strings;
at least one some platforms, memcmp() can use word-at-a-time comparisons.

Noah Misch, somewhat pared down.
---
 contrib/hstore/hstore_io.c      |  8 ++++----
 contrib/hstore/hstore_op.c      | 26 +++++++++++++-------------
 contrib/ltree/ltree_gist.c      |  2 +-
 contrib/ltree/ltree_op.c        |  8 ++++----
 src/backend/nodes/readfuncs.c   |  2 +-
 src/backend/utils/adt/varchar.c |  6 +++---
 src/backend/utils/adt/varlena.c | 14 +++++++-------
 7 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index 0058f5c1b3f..0d6f0b6b138 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -280,9 +280,9 @@ comparePairs(const void *a, const void *b)
 {
 	if (((Pairs *) a)->keylen == ((Pairs *) b)->keylen)
 	{
-		int			res = strncmp(((Pairs *) a)->key,
-								  ((Pairs *) b)->key,
-								  ((Pairs *) a)->keylen);
+		int			res = memcmp(((Pairs *) a)->key,
+								 ((Pairs *) b)->key,
+								 ((Pairs *) a)->keylen);
 
 		if (res)
 			return res;
@@ -324,7 +324,7 @@ hstoreUniquePairs(Pairs *a, int4 l, int4 *buflen)
 	while (ptr - a < l)
 	{
 		if (ptr->keylen == res->keylen &&
-			strncmp(ptr->key, res->key, res->keylen) == 0)
+			memcmp(ptr->key, res->key, res->keylen) == 0)
 		{
 			if (ptr->needfree)
 			{
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index 8d73a463aba..93d8cbcaebb 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -49,7 +49,7 @@ hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
 		stopMiddle = stopLow + (stopHigh - stopLow) / 2;
 
 		if (HS_KEYLEN(entries, stopMiddle) == keylen)
-			difference = strncmp(HS_KEY(entries, base, stopMiddle), key, keylen);
+			difference = memcmp(HS_KEY(entries, base, stopMiddle), key, keylen);
 		else
 			difference = (HS_KEYLEN(entries, stopMiddle) > keylen) ? 1 : -1;
 
@@ -263,7 +263,7 @@ hstore_delete(PG_FUNCTION_ARGS)
 		int			len = HS_KEYLEN(es, i);
 		char	   *ptrs = HS_KEY(es, bufs, i);
 
-		if (!(len == keylen && strncmp(ptrs, keyptr, keylen) == 0))
+		if (!(len == keylen && memcmp(ptrs, keyptr, keylen) == 0))
 		{
 			int			vallen = HS_VALLEN(es, i);
 
@@ -331,9 +331,9 @@ hstore_delete_array(PG_FUNCTION_ARGS)
 			int			skeylen = HS_KEYLEN(es, i);
 
 			if (skeylen == key_pairs[j].keylen)
-				difference = strncmp(HS_KEY(es, ps, i),
-									 key_pairs[j].key,
-									 key_pairs[j].keylen);
+				difference = memcmp(HS_KEY(es, ps, i),
+									key_pairs[j].key,
+									key_pairs[j].keylen);
 			else
 				difference = (skeylen > key_pairs[j].keylen) ? 1 : -1;
 		}
@@ -416,9 +416,9 @@ hstore_delete_hstore(PG_FUNCTION_ARGS)
 			int			s2keylen = HS_KEYLEN(es2, j);
 
 			if (skeylen == s2keylen)
-				difference = strncmp(HS_KEY(es, ps, i),
-									 HS_KEY(es2, ps2, j),
-									 skeylen);
+				difference = memcmp(HS_KEY(es, ps, i),
+									HS_KEY(es2, ps2, j),
+									skeylen);
 			else
 				difference = (skeylen > s2keylen) ? 1 : -1;
 		}
@@ -433,7 +433,7 @@ hstore_delete_hstore(PG_FUNCTION_ARGS)
 			if (snullval != HS_VALISNULL(es2, j)
 				|| (!snullval
 					&& (svallen != HS_VALLEN(es2, j)
-						|| strncmp(HS_VAL(es, ps, i), HS_VAL(es2, ps2, j), svallen) != 0)))
+						|| memcmp(HS_VAL(es, ps, i), HS_VAL(es2, ps2, j), svallen) != 0)))
 			{
 				HS_COPYITEM(ed, bufd, pd,
 							HS_KEY(es, ps, i), HS_KEYLEN(es, i),
@@ -526,9 +526,9 @@ hstore_concat(PG_FUNCTION_ARGS)
 			int			s2keylen = HS_KEYLEN(es2, s2idx);
 
 			if (s1keylen == s2keylen)
-				difference = strncmp(HS_KEY(es1, ps1, s1idx),
-									 HS_KEY(es2, ps2, s2idx),
-									 s1keylen);
+				difference = memcmp(HS_KEY(es1, ps1, s1idx),
+									HS_KEY(es2, ps2, s2idx),
+									s1keylen);
 			else
 				difference = (s1keylen > s2keylen) ? 1 : -1;
 		}
@@ -996,7 +996,7 @@ hstore_contains(PG_FUNCTION_ARGS)
 			if (nullval != HS_VALISNULL(ve, idx)
 				|| (!nullval
 					&& (vallen != HS_VALLEN(ve, idx)
-			|| strncmp(HS_VAL(te, tstr, i), HS_VAL(ve, vstr, idx), vallen))))
+			|| memcmp(HS_VAL(te, tstr, i), HS_VAL(ve, vstr, idx), vallen))))
 				res = false;
 		}
 		else
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 5fa7b59d32d..47a85bbabc2 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -546,7 +546,7 @@ gist_tqcmp(ltree *t, lquery *q)
 	while (an > 0 && bn > 0)
 	{
 		bl = LQL_FIRST(ql);
-		if ((res = strncmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
+		if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
 		{
 			if (al->len != bl->len)
 				return al->len - bl->len;
diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c
index 2ddfdec7eb1..2b048d4b7c5 100644
--- a/contrib/ltree/ltree_op.c
+++ b/contrib/ltree/ltree_op.c
@@ -68,7 +68,7 @@ ltree_compare(const ltree *a, const ltree *b)
 
 	while (an > 0 && bn > 0)
 	{
-		if ((res = strncmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
+		if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
 		{
 			if (al->len != bl->len)
 				return (al->len - bl->len) * 10 * (an + 1);
@@ -165,7 +165,7 @@ inner_isparent(const ltree *c, const ltree *p)
 	{
 		if (cl->len != pl->len)
 			return false;
-		if (strncmp(cl->name, pl->name, cl->len))
+		if (memcmp(cl->name, pl->name, cl->len))
 			return false;
 
 		pn--;
@@ -373,7 +373,7 @@ ltree_index(PG_FUNCTION_ARGS)
 			bptr = LTREE_FIRST(b);
 			for (j = 0; j < b->numlevel; j++)
 			{
-				if (!(aptr->len == bptr->len && strncmp(aptr->name, bptr->name, aptr->len) == 0))
+				if (!(aptr->len == bptr->len && memcmp(aptr->name, bptr->name, aptr->len) == 0))
 					break;
 				aptr = LEVEL_NEXT(aptr);
 				bptr = LEVEL_NEXT(bptr);
@@ -451,7 +451,7 @@ lca_inner(ltree **a, int len)
 			num = 0;
 			for (i = 0; i < Min(tmp, (*ptr)->numlevel - 1); i++)
 			{
-				if (l1->len == l2->len && strncmp(l1->name, l2->name, l1->len) == 0)
+				if (l1->len == l2->len && memcmp(l1->name, l2->name, l1->len) == 0)
 					num = i + 1;
 				else
 					break;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 933d58ada5f..d0d0b1cfe39 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1196,7 +1196,7 @@ parseNodeString(void)
 	token = pg_strtok(&length);
 
 #define MATCH(tokname, namelen) \
-	(length == namelen && strncmp(token, tokname, namelen) == 0)
+	(length == namelen && memcmp(token, tokname, namelen) == 0)
 
 	if (MATCH("QUERY", 5))
 		return_value = _readQuery();
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 34acfb36180..b3d7ba3f403 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -690,7 +690,7 @@ bpchareq(PG_FUNCTION_ARGS)
 	if (len1 != len2)
 		result = false;
 	else
-		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
+		result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
 
 	PG_FREE_IF_COPY(arg1, 0);
 	PG_FREE_IF_COPY(arg2, 1);
@@ -717,7 +717,7 @@ bpcharne(PG_FUNCTION_ARGS)
 	if (len1 != len2)
 		result = true;
 	else
-		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
+		result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
 
 	PG_FREE_IF_COPY(arg1, 0);
 	PG_FREE_IF_COPY(arg2, 1);
@@ -905,7 +905,7 @@ internal_bpchar_pattern_compare(BpChar *arg1, BpChar *arg2)
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
-	result = strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
+	result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
 	if (result != 0)
 		return result;
 	else if (len1 < len2)
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index ee83e2f3088..2fa740ac8c0 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -1286,7 +1286,7 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2)
 	 */
 	if (lc_collate_is_c())
 	{
-		result = strncmp(arg1, arg2, Min(len1, len2));
+		result = memcmp(arg1, arg2, Min(len1, len2));
 		if ((result == 0) && (len1 != len2))
 			result = (len1 < len2) ? -1 : 1;
 	}
@@ -1370,7 +1370,7 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2)
 			 */
 			if (result == 0)
 			{
-				result = strncmp(arg1, arg2, Min(len1, len2));
+				result = memcmp(arg1, arg2, Min(len1, len2));
 				if ((result == 0) && (len1 != len2))
 					result = (len1 < len2) ? -1 : 1;
 			}
@@ -1462,8 +1462,8 @@ texteq(PG_FUNCTION_ARGS)
 	if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
 		result = false;
 	else
-		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
-						  VARSIZE_ANY_EXHDR(arg1)) == 0);
+		result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
+						 VARSIZE_ANY_EXHDR(arg1)) == 0);
 
 	PG_FREE_IF_COPY(arg1, 0);
 	PG_FREE_IF_COPY(arg2, 1);
@@ -1485,8 +1485,8 @@ textne(PG_FUNCTION_ARGS)
 	if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
 		result = true;
 	else
-		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
-						  VARSIZE_ANY_EXHDR(arg1)) != 0);
+		result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
+						 VARSIZE_ANY_EXHDR(arg1)) != 0);
 
 	PG_FREE_IF_COPY(arg1, 0);
 	PG_FREE_IF_COPY(arg2, 1);
@@ -1612,7 +1612,7 @@ internal_text_pattern_compare(text *arg1, text *arg2)
 	len1 = VARSIZE_ANY_EXHDR(arg1);
 	len2 = VARSIZE_ANY_EXHDR(arg2);
 
-	result = strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
+	result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
 	if (result != 0)
 		return result;
 	else if (len1 < len2)
-- 
GitLab