From: Zijun Hu <[email protected]>

str_has_prefix() is frequently invoked to return length of the prefix
string if a string has another string as prefix, but its performance
is degraded by the strlen() loop contained.

Improve its performance by eliminating the strlen() loop.

Link: https://lore.kernel.org/all/[email protected]
Signed-off-by: Zijun Hu <[email protected]>
Cc: Rob Herring (Arm) <[email protected]>
---
 include/linux/string.h | 21 +--------------------
 lib/string.c           | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index 
e5f7defa277572719e1dbfdd264f3de6ef8544f1..394b76666ece0924c50264aaca39784d5630a2fe
 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -533,25 +533,6 @@ void memcpy_and_pad(void *dest, size_t dest_len, const 
void *src, size_t count,
               sizeof(*(obj)) - offsetof(typeof(*(obj)), member));      \
 })
 
-/**
- * str_has_prefix - Test if a string has a given prefix
- * @str: The string to test
- * @prefix: The string to see if @str starts with
- *
- * A common way to test a prefix of a string is to do:
- *  strncmp(str, prefix, sizeof(prefix) - 1)
- *
- * But this can lead to bugs due to typos, or if prefix is a pointer
- * and not a constant. Instead use str_has_prefix().
- *
- * Returns:
- * * strlen(@prefix) if @str starts with @prefix
- * * 0 if @str does not start with @prefix
- */
-static __always_inline size_t str_has_prefix(const char *str, const char 
*prefix)
-{
-       size_t len = strlen(prefix);
-       return strncmp(str, prefix, len) == 0 ? len : 0;
-}
+size_t str_has_prefix(const char *str, const char *prefix);
 
 #endif /* _LINUX_STRING_H_ */
diff --git a/lib/string.c b/lib/string.c
index 
ea52c8509328358e436766b1186a82419d45089d..17f1a070b190debc3eaeff6d1ae45b55bae69b29
 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -332,6 +332,39 @@ int strncmp(const char *cs, const char *ct, size_t count)
 EXPORT_SYMBOL(strncmp);
 #endif
 
+/**
+ * str_has_prefix - Test if a string has a given prefix
+ * @str: The string to test
+ * @prefix: The string to see if @str starts with
+ *
+ * A common way to test a prefix of a string is to do:
+ *  strncmp(str, prefix, sizeof(prefix) - 1)
+ *
+ * But this can lead to bugs due to typos, or if prefix is a pointer
+ * and not a constant. Instead use str_has_prefix().
+ *
+ * Returns:
+ * * strlen(@prefix) if @str starts with @prefix
+ * * 0 if @str does not start with @prefix
+ */
+size_t str_has_prefix(const char *str, const char *prefix)
+{
+       const char *p = prefix;
+       unsigned char c1, c2;
+
+       do {
+               c1 = *str++;
+               c2 = *p++;
+
+               if (c1 != c2)
+                       return c2 == '\0' ? p - 1 - prefix : 0;
+
+       } while (c2 != '\0');
+
+       return p - 1 - prefix;
+}
+EXPORT_SYMBOL(str_has_prefix);
+
 #ifndef __HAVE_ARCH_STRCHR
 /**
  * strchr - Find the first occurrence of a character in a string

-- 
2.34.1


Reply via email to