refcator demangler to avoid temporary vector and string creation. 21/244921/3
authorsub.mohanty@samsung.com <sub.mohanty@samsung.com>
Sat, 26 Sep 2020 00:21:29 +0000 (09:21 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Mon, 28 Sep 2020 01:20:33 +0000 (10:20 +0900)
-this patch reduces heap allocation by 130,000

Change-Id: Ic095319c11aea9e5235683f409b7ee846087d702

dali/internal/event/common/demangler-unix.cpp
dali/internal/event/common/demangler-windows.cpp
dali/internal/event/common/demangler.h

index 07a63a1..773b653 100644 (file)
  *
  */
 
+// EXTERNAL HEADER
+#include <string_view>
+
 // FILE HEADER
 #include <dali/internal/event/common/demangler.h>
 
-// INTERNAL HEADERS
-#include <dali/public-api/common/vector-wrapper.h>
-
 namespace
 {
-
-// true if character represent a digit
-inline bool IsDigit(char c)
-{
-  return (c >= '0' && c <= '9');
-}
-
-// Gets the number of characters (number is in string)
-//   start The start position to look for a number
-//   result The number as an integer
-//   returns the number of characters used to define the number ie '12' is 2
-size_t GetNumberOfCharacters(const std::string& s, const size_t& start, int& result)
+// Extracts the number from the src view and update the view.
+size_t ExtractNumber(std::string_view& src)
 {
-  size_t size = s.size();
-
-  size_t i = start;
-
-  int number = 0;
+  auto   IsDigit = [](char c) { return (c >= '0' && c <= '9'); };
+  size_t number  = 0;
 
-  for( ; i < size; ++i )
+  for(auto i = 0u; i < src.size(); ++i)
   {
-    char c = s.at(i);
+    char c = src[i];
     if( !IsDigit( c ) )
     {
+      //update the src view.
+      src.remove_prefix(i);
       break;
     }
     else
@@ -55,53 +44,41 @@ size_t GetNumberOfCharacters(const std::string& s, const size_t& start, int& res
     }
   }
 
-  if( i - start )
-  {
-    result = number;
-  }
-
-  return i - start;
+  return number;
 }
 
 /**
- * @brief Demangle a nested typeid name into its component parts.
+ * @brief Demangle a nested typeid name into its component parts and return
+ * the last component.
  * A nested type name is one containing namespaces and class names only.
- *   eg DemangleNestedNames(typeid(Dali::Actor).name());
+ *   eg ExtractDemangleNestedName(typeid(Dali::Actor).name());
  * @param[in] typeIdName The type id name string to demangle.
- * @returns the demangled list of names ie ["Dali","Actor"] or an empty list
+ * @returns the last component "Actor" or an empty string_view
  */
-std::vector<std::string> DemangleNestedNames(const char *typeIdName)
+std::string_view ExtractDemangleNestedName(std::string_view mangledName)
 {
-  // Demangle class name mangled according to the Itanium C++ ABI
-  // Returns demangled names ie "N4Dali8Internal5ActorE" is ["Dali","Internal","Actor"]
-  std::vector<std::string> ret;
-
-  const std::string mangledName(typeIdName);
-
-
-  size_t size = mangledName.size();
-
-  if( size >= 2 )
+  if(mangledName.empty())
   {
-    int number = 0;
-    size_t start = 0;
-
-    // If the class isnt nested in a namespace then it just starts with the
-    // number of characters
-    if(mangledName[0] == 'N' && mangledName[size-1]  == 'E')
-    {
-      start = 1;
-    }
+    return {};
+  }
 
-    while( size_t chars = GetNumberOfCharacters(mangledName, start, number) )
-    {
-      ret.push_back( mangledName.substr( start + chars, number ) );
+  // classes nested inside a namespace starts with 'N' and ends with 'E'
+  // so trim those
+  if(mangledName.front() == 'N' && mangledName.back() == 'E')
+  {
+    mangledName.remove_prefix(1);
+    mangledName.remove_suffix(1);
+  }
 
-      start += chars + number;
-    }
+  std::string_view result;
+  while(!mangledName.empty())
+  {
+    auto length = ExtractNumber(mangledName);
+    result      = {mangledName.data(), length};
+    mangledName.remove_prefix(length);
   }
 
-  return ret;
+  return result;
 }
 
 } // anon namespace
@@ -111,18 +88,9 @@ namespace Dali
 
 namespace Internal
 {
-
-const std::string DemangleClassName(const char *typeIdName)
+std::string DemangleClassName(const char* typeIdName)
 {
-  std::string name;
-  std::vector<std::string> names = DemangleNestedNames(typeIdName);
-
-  if( names.size() )
-  {
-    name = names[ names.size() - 1 ];
-  }
-
-  return name;
+  return std::string(ExtractDemangleNestedName(typeIdName));
 }
 
 } // namespace Internal
index 9d6612a..cdfc58b 100644 (file)
@@ -23,8 +23,7 @@ namespace Dali
 
 namespace Internal
 {
-
-const std::string DemangleClassName(const char *typeIdName)
+std::string DemangleClassName(const char* typeIdName)
 {
   std::string name = typeIdName;
   int index = name.find_last_of(' ');
index 4d9790b..647e015 100644 (file)
@@ -32,7 +32,7 @@ namespace Internal
  * @param[in] typeIdName The type id name string to demangle.
  * @returns the class name ie "Actor" or an empty string
  */
-const std::string DemangleClassName(const char *typeIdName);
+std::string DemangleClassName(const char* typeIdName);
 
 } // namespace Internal