improve find performance is case of one output argument 16/17216/2
Antoine ELIAS [Thu, 17 Sep 2015 15:22:30 +0000 (17:22 +0200)]
a = rand(3000,3000);
tic();find(a>0.5);toc

6.0.0 alpha1 around 0.350 second
after path : < 0.100 second

Change-Id: I83e01862134320dd0f22753590105c66ec31620d

scilab/modules/boolean/sci_gateway/cpp/sci_find.cpp
scilab/modules/boolean/tests/unit_tests/find.dia.ref [new file with mode: 0644]
scilab/modules/boolean/tests/unit_tests/find.tst [new file with mode: 0644]

index 93fbf2d..c04887c 100644 (file)
@@ -63,9 +63,12 @@ types::Function::ReturnValue sci_find(types::typed_list &in, int _iRetCount, typ
     if (in[0]->isBool())
     {
         types::Bool* pB = in[0]->getAs<types::Bool>();
-        for (int i = 0 ; (iMax == -1 || iValues < iMax) && i < pB->getSize() ; i++)
+        int size = pB->getSize();
+        int* p = pB->get();
+        iMax = iMax == -1 ? size : std::min(iMax, size);
+        for (int i = 0 ; i < iMax ; i++)
         {
-            if (pB->get(i))
+            if (p[i])
             {
                 piIndex[iValues] = i;
                 iValues++;
@@ -75,9 +78,12 @@ types::Function::ReturnValue sci_find(types::typed_list &in, int _iRetCount, typ
     else if (in[0]->isDouble())
     {
         types::Double* pD = in[0]->getAs<types::Double>();
-        for (int i = 0 ; (iMax == -1 || iValues < iMax) && i < pD->getSize() ; i++)
+        int size = pD->getSize();
+        double* p = pD->get();
+        iMax = iMax == -1 ? size : std::min(iMax, size);
+        for (int i = 0; i < iMax; i++)
         {
-            if (pD->get(i))
+            if (p[i])
             {
                 piIndex[iValues] = i;
                 iValues++;
@@ -92,8 +98,9 @@ types::Function::ReturnValue sci_find(types::typed_list &in, int _iRetCount, typ
         int* pRows = new int[iNNZ * 2];
         pSP->outputRowCol(pRows);
         int *pCols = pRows + iNNZ;
+        iMax = iMax == -1 ? iNNZ : std::min(iMax, iNNZ);
 
-        for (int i = 0 ; (iMax == -1 || iValues < iMax) && i < iNNZ ; i++)
+        for (int i = 0; i < iMax; i++)
         {
             piIndex[iValues] = (pCols[i] - 1) * iRows + (pRows[i] - 1);
             iValues++;
@@ -111,7 +118,8 @@ types::Function::ReturnValue sci_find(types::typed_list &in, int _iRetCount, typ
         pSB->outputRowCol(pRows);
         int* pCols = pRows + iNNZ;
 
-        for (int i = 0 ; (iMax == -1 || iValues < iMax) && i < iNNZ ; i++)
+        iMax = iMax == -1 ? iNNZ : std::min(iMax, iNNZ);
+        for (int i = 0; i < iMax; i++)
         {
             piIndex[iValues] = (pCols[i] - 1) * iRows + (pRows[i] - 1);
             iValues++;
@@ -137,6 +145,21 @@ types::Function::ReturnValue sci_find(types::typed_list &in, int _iRetCount, typ
     }
     else
     {
+        if (_iRetCount == 1)
+        {
+            types::Double* dbl = new types::Double(1, iValues);
+            double* p = dbl->get();
+
+            for (int i = 0; i < iValues; ++i)
+            {
+                p[i] = static_cast<double>(piIndex[i]) + 1;
+            }
+
+            delete[] piIndex;
+            out.push_back(dbl);
+            return types::Function::OK;
+        }
+
         int* piRefDims = pGT->getDimsArray();
         int iRefDims = pGT->getDims();
 
diff --git a/scilab/modules/boolean/tests/unit_tests/find.dia.ref b/scilab/modules/boolean/tests/unit_tests/find.dia.ref
new file mode 100644 (file)
index 0000000..2e003cc
--- /dev/null
@@ -0,0 +1,12 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) - 2015 - Scilab Enterprises - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+a = zeros(1,2000);
+a(1:2:2000)=1:1000;
+assert_checkequal(and(find(a==0)==(2:2:2000)), %T);
diff --git a/scilab/modules/boolean/tests/unit_tests/find.tst b/scilab/modules/boolean/tests/unit_tests/find.tst
new file mode 100644 (file)
index 0000000..8ac43ed
--- /dev/null
@@ -0,0 +1,14 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) - 2015 - Scilab Enterprises - Calixte DENIZET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+
+a = zeros(1,2000);
+a(1:2:2000)=1:1000;
+
+assert_checkequal(and(find(a==0)==(2:2:2000)), %T);
\ No newline at end of file