String: share a common empty string value 28/19128/1
Clément DAVID [Fri, 3 Feb 2017 12:06:14 +0000 (13:06 +0100)]
Change-Id: I1dbf372a8c4f94a0903254cd929700012c020891

scilab/CHANGES.md
scilab/modules/ast/includes/types/string.hxx
scilab/modules/ast/src/cpp/types/string.cpp
scilab/modules/string/sci_gateway/cpp/sci_emptystr.cpp

index 446589b..a958956 100644 (file)
@@ -65,13 +65,10 @@ Packaging & Supported Operating Systems
 * [SSE2](https://en.wikipedia.org/wiki/SSE2), Streaming SIMD Extensions 2 support is mandatory.
 
 
-Language changes
-----------------
-
-
 Feature changes and additions
 -----------------------------
 
+* Empty strings are used as the default values on String allocation
 
 Help pages:
 -----------
@@ -105,5 +102,5 @@ Bug Fixes
 ---------
 
 ### Bugs fixed in 6.1.0:
-* [#XXXX](http://bugzilla.scilab.org/show_bug.cgi?id=XXXX): dummy bug report example
+* [#14604](http://bugzilla.scilab.org/show_bug.cgi?id=14604): `emptystr()` is 40x slower with 6.0.0 wrt 5.5.2
 
index af810c9..a26a0dd 100644 (file)
@@ -44,6 +44,8 @@ public :
     String(const char *_pstData);
     virtual                 ~String();
 
+    static wchar_t* nullValue();
+
     void                    whoAmI();
 
     virtual String*         set(int _iPos, const wchar_t* _pwstData);
@@ -105,7 +107,10 @@ private :
     virtual wchar_t*        copyValue(wchar_t* _pwstData);
     virtual wchar_t*        copyValue(const wchar_t* _pwstData);
     virtual String*         createEmpty(int _iDims, int* _piDims, bool _bComplex = false);
-    virtual wchar_t*        getNullValue();
+    virtual wchar_t*        getNullValue()
+    {
+        return nullValue();
+    };
     virtual void            deleteAll();
     virtual void            deleteImg();
     virtual wchar_t**       allocData(int _iSize);
index 569cffe..de7555f 100644 (file)
@@ -118,7 +118,7 @@ void String::deleteString(int _iPos)
 {
     if (m_pRealData != NULL)
     {
-        if (m_pRealData[_iPos] != NULL)
+        if (m_pRealData[_iPos] != NULL && m_pRealData[_iPos] != String::nullValue())
         {
             FREE(m_pRealData[_iPos]);
             m_pRealData[_iPos] = NULL;
@@ -546,9 +546,12 @@ bool String::operator!=(const InternalType& it)
     return !(*this == it);
 }
 
-wchar_t* String::getNullValue()
+static std::wstring null = L"";
+wchar_t* String::nullValue()
 {
-    return os_wcsdup(L"");
+    // The null value pointer is shared to speed up "" assignement
+    // Empty strings creation can then be done without memory allocation
+    return (wchar_t*) null.data();
 }
 
 String* String::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
@@ -558,6 +561,11 @@ String* String::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
 
 wchar_t* String::copyValue(wchar_t* _pwstData)
 {
+    if (_pwstData == nullValue())
+    {
+        return nullValue();
+    }
+
     try
     {
         return os_wcsdup(_pwstData);
@@ -574,12 +582,17 @@ wchar_t* String::copyValue(wchar_t* _pwstData)
 
 wchar_t* String::copyValue(const wchar_t* _pwstData)
 {
+    if (_pwstData == nullValue())
+    {
+        return nullValue();
+    }
+
     return os_wcsdup(_pwstData);
 }
 
 void String::deleteData(wchar_t* data)
 {
-    if (data)
+    if (data && data != nullValue())
     {
         // data are always allocated using C-like malloc API
         FREE(data);
index f08d374..2e3c04a 100644 (file)
@@ -104,7 +104,7 @@ types::Function::ReturnValue sci_emptystr(types::typed_list &in, int _iRetCount,
     wchar_t** strs = ret->get();
     for (int i = 0; i < size; ++i)
     {
-        strs[i] = os_wcsdup(L"");
+        strs[i] = types::String::nullValue();
     }
 
     out.push_back(ret);