IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19539


Ignore:
Timestamp:
Sep 12, 2008, 12:36:29 PM (18 years ago)
Author:
Paul Price
Message:

Optimising psPixelsConcatenate: use of qsort took ages. Split into two functions: psPixelsConcatenate (joing two pixel lists) and psPixelsDuplicates (remove duplicates in a list; works nicely in-place), and using PSSORT instead of qsort. Much faster!

Location:
trunk/psLib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/types/psPixels.c

    r19240 r19539  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2008-08-27 22:29:48 $
     9 *  @version $Revision: 1.43 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2008-09-12 22:36:29 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2121
    2222#include "psAbort.h"
    23 #include "psPixels.h"
     23#include "psSort.h"
    2424#include "psMemory.h"
    2525#include "psAssert.h"
    2626#include "psError.h"
    2727
     28#include "psPixels.h"
     29
    2830#define PIXELS_DEFAULT_ADD 10           // Default number to add, if not specified
    2931
     
    3537    psFree(pixels->data);
    3638}
    37 
    38 // for use by qsort, etc.
    39 static int comparePixelCoord(psPixelCoord* coord1,
    40                              psPixelCoord* coord2)
    41 {
    42     // check row first
    43     if (coord1->y < coord2->y) {
    44         return -1;
    45     }
    46 
    47     if (coord1->y > coord2->y) {
    48         return 1;
    49     }
    50 
    51     // rows are the same, so check column
    52     if (coord1->x < coord2->x) {
    53         return -1;
    54     }
    55 
    56     if (coord1->x > coord2->x) {
    57         return 1;
    58     }
    59 
    60     return 0;
    61 }
    62 
    6339
    6440static psPixels *pixelsAlloc(const char *file,
     
    254230    }
    255231
    256     // sort the OUT array to help in searching for duplicates later
    257     qsort(out->data, out->n, sizeof(psPixelCoord), (qsortCompareFunc)comparePixelCoord);
    258 
    259     // add non-duplicate values in pixels to the end of the output list (unsorted!)
    260     long numInPix = pixels->n;          // Number of input pixels
    261     long numOutPix = out->n;            // (Original) number of output pixels
    262     for (long i = 0; i < numInPix; i++) {
    263         psPixelCoord pix = pixels->data[i]; // Coordinate of interest
    264         if (!bsearch(&pix, out->data, numOutPix, sizeof(psPixelCoord), (qsortCompareFunc)comparePixelCoord)) {
    265             psPixelsAdd(out, out->nalloc, pix.x, pix.y);
    266         }
    267     }
     232    long numIn = pixels->n;             // Number of input pixels
     233    long numOut = out->n;               // Number of (original) output pixels
     234    out = psPixelsRealloc(out, numIn + numOut);
     235    memcpy(&out->data[numOut], pixels->data, numIn * sizeof(psPixelCoord));
     236    out->n = numIn + numOut;
     237
     238    return out;
     239}
     240
     241// Macro functions for sorting a pixel list
     242#define PSPIXELS_SORT_COMPARE(A,B) (data[A].y < data[B].y || data[A].x < data[B].x)
     243#define PSPIXELS_SORT_SWAP(TYPE,A,B) { \
     244    if (A != B) { \
     245        TYPE temp = data[A]; \
     246        data[A] = data[B]; \
     247        data[B] = temp; \
     248    } \
     249}
     250
     251psPixels* psPixelsDuplicates(psPixels *out, const psPixels *pixels)
     252{
     253    PS_ASSERT_PIXELS_NON_NULL(pixels, NULL);
     254    if (pixels->n <= 1) {
     255        return psPixelsCopy(out, pixels);
     256    }
     257
     258    long numIn = pixels->n;          // Number of input pixels
     259    out = psPixelsRealloc(out, numIn);
     260
     261    psPixelCoord *data = pixels->data;  // Dereference input
     262    PSSORT(numIn, PSPIXELS_SORT_COMPARE, PSPIXELS_SORT_SWAP, psPixelCoord);
     263
     264    long numOut = 0;                     // Number of output pixels
     265    for (long i = 0; i < numIn; numOut++) {
     266        psPixelCoord pix = data[i];     // Coordinates of interest
     267        for (i++; i < numIn && data[i].x == pix.x && data[i].y == pix.y; i++); // No action
     268        out->data[numOut] = pix;
     269    }
     270    out->n = numOut;
    268271
    269272    return out;
  • trunk/psLib/src/types/psPixels.h

    r19056 r19539  
    66 *  @author Robert DeSonia, MHPCC
    77 *
    8  *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2008-08-14 03:18:41 $
     8 *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2008-09-12 22:36:29 $
    1010 *
    1111 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    214214 *  out is NULL, a new psPixels shall be allocated, and the contents of
    215215 *  pixels simply copied in. If pixels is NULL, the function shall generate
    216  *  an error and return NULL. The function shall take care to ensure that
    217  *  there are no duplicate pixels in out.
     216 *  an error and return NULL.
    218217 *
    219218 *  @return psPixels         Concatenated psPixel list
     
    224223);
    225224
     225/// Remove duplicates in a list of pixels
     226psPixels* psPixelsDuplicates(
     227    psPixels *out, ///< Output list with duplicates removed, or NULL
     228    const psPixels *pixels ///< Input list of pixels
     229    );
    226230
    227231/** Prints a psPixels to specified destination.
  • trunk/psLib/src/types/psTree.h

    r18335 r19539  
    33
    44#include <psError.h>
     5#include <psVector.h>
    56
    67/// An array of coordinates for the tree
  • trunk/psLib/test/types/tap_psPixels_all.c

    r17515 r19539  
    5151    }
    5252    //Make sure psMemCheckPixels works correctly - return false
    53     // XXX EAM : disabled -- failing test causes segfault 
     53    // XXX EAM : disabled -- failing test causes segfault
    5454    if (0) {
    5555        int j = 2;
     
    349349    {
    350350        psMemId id = psMemGetId();
    351         psPixels *outPixels = psPixelsAlloc(5);
     351        psPixels *outPixels = psPixelsAlloc(6);
    352352        in.x = 1.0;
    353353        in.y = 1.0;
     
    360360        in.x = 2.0;
    361361        psPixelsSet(outPixels, 4, in);  //2, 1
    362         psPixels *testPixels = psPixelsAlloc(6);
     362        in.y = 2.0;
     363        psPixelsSet(outPixels, 5, in);  //2, 2
     364        psPixels *testPixels = psPixelsAlloc(7);
    363365        in.x = 1.0;
    364366        in.y = 1.0;
     
    370372        in.x = 2.0;
    371373        psPixelsSet(testPixels, 3, in);  //2, 1
     374        in.y = 2.0;
     375        psPixelsSet(testPixels, 4, in);  //2, 2
    372376        in.x = 1.0;
    373         psPixelsSet(testPixels, 4, in);  //1, 1
     377        psPixelsSet(testPixels, 5, in);  //1, 2
    374378        in.x = 5.0;
    375379        in.y = 3.0;
    376         psPixelsSet(testPixels, 5, in);  //5, 3
     380        psPixelsSet(testPixels, 6, in);  //5, 3
    377381        outPixels = psPixelsConcatenate(outPixels, testPixels);
    378         ok(outPixels->n == 6, "psPixelsConcatenate:  return properly concatenate pixel list for valid inputs.");
     382        outPixels = psPixelsDuplicates(outPixels, outPixels);
     383        // Should be 5 entries: (1,1) (2,1) (1,2) (2,2) (5,3)
     384        ok(outPixels->n == 5, "psPixelsConcatenate:  return properly concatenate pixel list for valid inputs.");
    379385        psFree(testPixels);
    380386        psFree(outPixels);
Note: See TracChangeset for help on using the changeset viewer.