Bug 1247359 - micro-optimize the common case of String{Begins,End}With; r=erahm
authorNathan Froyd <froydnj@mozilla.com>
Wed, 10 Feb 2016 14:31:06 -0500
changeset 330500 e4afb9798bcb817b87f00fb02ff772e9cbd19880
parent 330499 09c28fca8ee7b9dc414562a846554ab11a2be499
child 330501 ab6e685f82b0b38abb888e127755d62493c3e799
push id10773
push userjyavenard@mozilla.com
push dateThu, 11 Feb 2016 23:46:51 +0000
reviewerserahm
bugs1247359
milestone47.0a1
Bug 1247359 - micro-optimize the common case of String{Begins,End}With; r=erahm StringBeginsWith (resp. StringEndsWith) takes a defaulted nsStringComparator object for doing comparisons. The flexibility this affords is great, but the cost is not: nsStringComparator has virtual methods, so initializing that defaulted object (at every callsite) requires a temporary object whose vtable must be initialized. Since the overwhemingly common case is to use the default comparator anyway, we should not use defaulted arguments and instead provide the default comparator/user-provided comparator cases as separate overloads. This change eliminates the virtual call for the majority of callsites and reduces codesize as well.
xpcom/string/nsReadableUtils.cpp
xpcom/string/nsReadableUtils.h
--- a/xpcom/string/nsReadableUtils.cpp
+++ b/xpcom/string/nsReadableUtils.cpp
@@ -1022,53 +1022,97 @@ CountCharInReadable(const nsACString& aS
     }
     ++begin;
   }
 
   return count;
 }
 
 bool
+StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring)
+{
+  nsAString::size_type src_len = aSource.Length(),
+                       sub_len = aSubstring.Length();
+  if (sub_len > src_len) {
+    return false;
+  }
+  return Substring(aSource, 0, sub_len).Equals(aSubstring);
+}
+
+bool
 StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
                  const nsStringComparator& aComparator)
 {
   nsAString::size_type src_len = aSource.Length(),
                        sub_len = aSubstring.Length();
   if (sub_len > src_len) {
     return false;
   }
   return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
 }
 
 bool
+StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring)
+{
+  nsACString::size_type src_len = aSource.Length(),
+                        sub_len = aSubstring.Length();
+  if (sub_len > src_len) {
+    return false;
+  }
+  return Substring(aSource, 0, sub_len).Equals(aSubstring);
+}
+
+bool
 StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
                  const nsCStringComparator& aComparator)
 {
   nsACString::size_type src_len = aSource.Length(),
                         sub_len = aSubstring.Length();
   if (sub_len > src_len) {
     return false;
   }
   return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
 }
 
 bool
+StringEndsWith(const nsAString& aSource, const nsAString& aSubstring)
+{
+  nsAString::size_type src_len = aSource.Length(),
+                       sub_len = aSubstring.Length();
+  if (sub_len > src_len) {
+    return false;
+  }
+  return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring);
+}
+
+bool
 StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
                const nsStringComparator& aComparator)
 {
   nsAString::size_type src_len = aSource.Length(),
                        sub_len = aSubstring.Length();
   if (sub_len > src_len) {
     return false;
   }
   return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring,
                                                                aComparator);
 }
 
 bool
+StringEndsWith(const nsACString& aSource, const nsACString& aSubstring)
+{
+  nsACString::size_type src_len = aSource.Length(),
+                        sub_len = aSubstring.Length();
+  if (sub_len > src_len) {
+    return false;
+  }
+  return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring);
+}
+
+bool
 StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
                const nsCStringComparator& aComparator)
 {
   nsACString::size_type src_len = aSource.Length(),
                         sub_len = aSubstring.Length();
   if (sub_len > src_len) {
     return false;
   }
--- a/xpcom/string/nsReadableUtils.h
+++ b/xpcom/string/nsReadableUtils.h
@@ -381,28 +381,28 @@ bool FindCharInReadable(char aChar, nsAC
 /**
 * Finds the number of occurences of |aChar| in the string |aStr|
 */
 uint32_t CountCharInReadable(const nsAString& aStr,
                              char16_t aChar);
 uint32_t CountCharInReadable(const nsACString& aStr,
                              char aChar);
 
+bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring);
 bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
-                      const nsStringComparator& aComparator =
-                        nsDefaultStringComparator());
+                      const nsStringComparator& aComparator);
+bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring);
 bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
-                      const nsCStringComparator& aComparator =
-                        nsDefaultCStringComparator());
+                      const nsCStringComparator& aComparator);
+bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring);
 bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
-                    const nsStringComparator& aComparator =
-                      nsDefaultStringComparator());
+                    const nsStringComparator& aComparator);
+bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring);
 bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
-                    const nsCStringComparator& aComparator =
-                      nsDefaultCStringComparator());
+                    const nsCStringComparator& aComparator);
 
 const nsAFlatString& EmptyString();
 const nsAFlatCString& EmptyCString();
 
 const nsAFlatString& NullString();
 const nsAFlatCString& NullCString();
 
 /**