Bug #3188 fixed - `part()` was slower since 4.1.2 35/21435/1
Clement David [Wed, 11 Mar 2020 10:34:02 +0000 (11:34 +0100)]
Change-Id: Ief42881ad2dcb49134abb1f9172603866790e5ee

scilab/CHANGES.md
scilab/modules/string/sci_gateway/cpp/sci_part.cpp
scilab/modules/string/tests/benchmarks/bench_part2_matrix.tst [new file with mode: 0644]

index 64c2623..f8ac952 100644 (file)
@@ -265,6 +265,7 @@ Bug Fixes
 ---------
 
 ### Bugs fixed in 6.1.0:
+* [#3188](https://bugzilla.scilab.org/3188): `part()` was slower than in Scilab 4.1.2.
 * [#16342](https://bugzilla.scilab.org/16342): `strcat()` was much slower in Scilab 6.0.2.
 
 
index 5c6c028..936f808 100644 (file)
   c(i,j)  is the Input_StringMatrixing  "s[v(1)]...s[v(n)]"  (  s=mp(i,j)  ).
                                                                           */
 /*------------------------------------------------------------------------*/
-#include "string_gw.hxx"
+#include "double.hxx"
 #include "funcmanager.hxx"
 #include "function.hxx"
-#include "string.hxx"
-#include "double.hxx"
 #include "overload.hxx"
+#include "string.hxx"
+#include "string_gw.hxx"
 
 extern "C"
 {
-#include <string.h>
-#include <stdio.h>
 #include "Scierror.h"
-#include "localization.h"
 #include "freeArrayOfString.h"
+#include "localization.h"
 #include "partfunction.h"
+#include <stdio.h>
+#include <string.h>
 }
 /*--------------------------------------------------------------------------*/
-types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, types::typed_list &out)
+types::Function::ReturnValue sci_part(types::typed_list& in, int _iRetCount, types::typed_list& out)
 {
     if (in.size() != 2)
     {
@@ -67,7 +67,7 @@ types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, typ
 
     if (in[1]->isDouble() == false)
     {
-        std::wstring wstFuncName = L"%"  + in[1]->getShortTypeStr() + L"_part";
+        std::wstring wstFuncName = L"%" + in[1]->getShortTypeStr() + L"_part";
         return Overload::call(wstFuncName, in, _iRetCount, out);
     }
 
@@ -81,7 +81,7 @@ types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, typ
 
     size_t i_len = pD->getSize();
     std::vector<int> index(i_len);
-    for (int i = 0 ; i < i_len; i++)
+    for (int i = 0; i < i_len; i++)
     {
         int idx = static_cast<int>(pD->get()[i]);
         if (idx < 1)
@@ -93,16 +93,22 @@ types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, typ
         index[i] = idx;
     }
 
-    //wchar_t** pwstOut = partfunctionW(pS->get(), pS->getRows(), pS->getCols(), piIndex, pD->getSize());
     types::String* pOut = new types::String(pS->getRows(), pS->getCols());
     std::wstring string_in;
-    std::wstring string_out;
 
+    // allocate the output strings
+    std::wstring string_out(i_len, L' ');
     for (int i = 0; i < pS->getSize(); ++i)
     {
-        string_in.assign(pS->get()[i]);
-        size_t s_len = string_in.size();
-        string_out.assign(i_len, L' ');
+        pOut->set(i, string_out.data());
+    }
+
+    // part() algorithm
+    for (int i = 0; i < pS->getSize(); ++i)
+    {
+        wchar_t* wcs_in = pS->get()[i];
+        wchar_t* wcs_out = pOut->get()[i];
+        size_t s_len = wcslen(wcs_in);
 
         for (int j = 0; j < i_len; ++j)
         {
@@ -111,10 +117,8 @@ types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, typ
                 continue;
             }
 
-            string_out[j] = string_in[index[j] - 1];
+            wcs_out[j] = wcs_in[index[j] - 1];
         }
-
-        pOut->set(i, string_out.data());
     }
 
     out.push_back(pOut);
diff --git a/scilab/modules/string/tests/benchmarks/bench_part2_matrix.tst b/scilab/modules/string/tests/benchmarks/bench_part2_matrix.tst
new file mode 100644 (file)
index 0000000..e90896a
--- /dev/null
@@ -0,0 +1,24 @@
+// =============================================================================\r
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab\r
+// Copyright (C) 2020 - ESI Group - Clement DAVID\r
+//\r
+//  This file is distributed under the same license as the Scilab package.\r
+// =============================================================================\r
+\r
+//==============================================================================\r
+// Benchmark for part function\r
+//==============================================================================\r
+\r
+// <-- BENCH NB RUN : 400 -->\r
+// M*N are equals to bench_part2.tst NB RUN, bench timing should be the similar\r
+M=5;\r
+N=5;\r
+\r
+c = 1e5;\r
+str = strcat(string(int(rand(1, c) * 10)));\r
+idx = int(rand(1, c) * c + 1);\r
+str = str(ones(M, N));\r
+\r
+// <-- BENCH START -->\r
+part(str, idx);\r
+// <-- BENCH END -->\r