Leptonica 1.68
C Image Processing Library

pixalloc_reg.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  * pixalloc_reg.c
00018  *
00019  *   Tests custom pix allocator.
00020  *
00021  *   The custom allocator is intended for situations where a number of large
00022  *   pix will be repeatedly allocated and freed over the lifetime of a program.
00023  *   If those pix are large, relying on malloc and free can result in
00024  *   fragmentation, even if there are no small memory leaks in the program.
00025  *
00026  *   Here we test the allocator in two situations:
00027  *     * a small number of relatively large pix
00028  *     * a large number of very small pix
00029  *
00030  *   For the second case, timing shows that the custom allocator does
00031  *   about as well as (malloc, free), even for thousands of very small pix.
00032  *   (Turn off logging to get a fair comparison).
00033  */
00034 
00035 #include <math.h>
00036 #include "allheaders.h"
00037 
00038 static const l_int32 logging = FALSE;
00039 
00040 static const l_int32 ncopies = 2;
00041 static const l_int32 nlevels = 4;
00042 static const l_int32 ntimes = 30;
00043 
00044 
00045 PIXA *GenerateSetOfMargePix(void);
00046 void CopyStoreClean(PIXA *pixas, l_int32 nlevels, l_int32 ncopies);
00047 
00048 
00049 main(int    argc,
00050      char **argv)
00051 {
00052 l_int32      i;
00053 BOXA        *boxa;
00054 NUMA        *nas, *nab;
00055 PIX         *pixs;
00056 PIXA        *pixa, *pixas;
00057 static char  mainName[] = "pixalloc_reg";
00058 
00059 
00060     /* ----------------- Custom with a few large pix -----------------*/
00061         /* Set up pms */
00062     nas = numaCreate(4);  /* small */
00063     numaAddNumber(nas, 5);   
00064     numaAddNumber(nas, 4);
00065     numaAddNumber(nas, 3);
00066     numaAddNumber(nas, 2);
00067     setPixMemoryManager(pmsCustomAlloc, pmsCustomDealloc);
00068     pmsCreate(200000, 400000, nas, "/tmp/junk1.log");
00069 
00070         /* Make the pix and do successive copies and removals of the copies */
00071     pixas = GenerateSetOfMargePix();
00072     startTimer();
00073     for (i = 0; i < ntimes; i++)
00074         CopyStoreClean(pixas, nlevels, ncopies);
00075     fprintf(stderr, "Time (big pix; custom) = %7.3f sec\n", stopTimer());
00076 
00077         /* Clean up */
00078     numaDestroy(&nas);
00079     pixaDestroy(&pixas);
00080     pmsDestroy();
00081 
00082 
00083     /* ----------------- Standard with a few large pix -----------------*/
00084     setPixMemoryManager(malloc, free);
00085 
00086         /* Make the pix and do successive copies and removals of the copies */
00087     startTimer();
00088     pixas = GenerateSetOfMargePix();
00089     for (i = 0; i < ntimes; i++)
00090         CopyStoreClean(pixas, nlevels, ncopies);
00091     fprintf(stderr, "Time (big pix; standard) = %7.3f sec\n", stopTimer());
00092     pixaDestroy(&pixas);
00093 
00094 
00095     /* ----------------- Custom with many small pix -----------------*/
00096         /* Set up pms */
00097     nab = numaCreate(10);
00098     numaAddNumber(nab, 2000);
00099     numaAddNumber(nab, 2000);
00100     numaAddNumber(nab, 2000);
00101     numaAddNumber(nab, 500);
00102     numaAddNumber(nab, 100);
00103     numaAddNumber(nab, 100);
00104     numaAddNumber(nab, 100);
00105     setPixMemoryManager(pmsCustomAlloc, pmsCustomDealloc);
00106     if (logging)   /* use logging == 0 for speed comparison */
00107         pmsCreate(20, 40, nab, "/tmp/junk2.log");
00108     else
00109         pmsCreate(20, 40, nab, NULL);
00110     pixs = pixRead("feyn.tif");
00111 
00112     startTimer();
00113     for (i = 0; i < 5; i++) {
00114         boxa = pixConnComp(pixs, &pixa, 8);
00115         boxaDestroy(&boxa);
00116         pixaDestroy(&pixa);
00117     }
00118 
00119     numaDestroy(&nab);
00120     pixDestroy(&pixs);
00121     pmsDestroy();
00122     fprintf(stderr, "Time (custom) = %7.3f sec\n", stopTimer());
00123 
00124 
00125     /* ----------------- Standard with many small pix -----------------*/
00126     setPixMemoryManager(malloc, free);
00127     pixs = pixRead("feyn.tif");
00128 
00129     startTimer();
00130     for (i = 0; i < 5; i++) {
00131         boxa = pixConnComp(pixs, &pixa, 8);
00132         boxaDestroy(&boxa);
00133         pixaDestroy(&pixa);
00134     }
00135     pixDestroy(&pixs);
00136     fprintf(stderr, "Time (standard) = %7.3f sec\n", stopTimer());
00137     return 0;
00138 }
00139 
00140 
00141 PIXA *
00142 GenerateSetOfMargePix(void)
00143 {
00144 l_float32  factor;
00145 BOX   *box;
00146 PIX   *pixs, *pixt1, *pixt2, *pixt3, *pixt4;
00147 PIXA  *pixa;
00148 
00149     pixs = pixRead("marge.jpg");
00150     box = boxCreate(130, 93, 263, 253);
00151     factor = sqrt(2.0);
00152     pixt1 = pixClipRectangle(pixs, box, NULL);  /* 266 KB */
00153     pixt2 = pixScale(pixt1, factor, factor);    /* 532 KB */
00154     pixt3 = pixScale(pixt2, factor, factor);    /* 1064 KB */
00155     pixt4 = pixScale(pixt3, factor, factor);    /* 2128 KB */
00156     pixa = pixaCreate(4);
00157     pixaAddPix(pixa, pixt1, L_INSERT);
00158     pixaAddPix(pixa, pixt2, L_INSERT);
00159     pixaAddPix(pixa, pixt3, L_INSERT);
00160     pixaAddPix(pixa, pixt4, L_INSERT);
00161     boxDestroy(&box);
00162     pixDestroy(&pixs);
00163     return pixa;
00164 }
00165 
00166 
00167 void
00168 CopyStoreClean(PIXA    *pixas,
00169                l_int32  nlevels,
00170                l_int32  ncopies)
00171 {
00172 l_int32  i, j;
00173 PIX     *pix, *pixt;
00174 PIXA    *pixa;
00175 PIXAA   *paa;
00176 
00177     paa = pixaaCreate(0);
00178     for (i = 0; i < nlevels ; i++) {
00179         pixa = pixaCreate(0);
00180         pixaaAddPixa(paa, pixa, L_INSERT);
00181         pix = pixaGetPix(pixas, i, L_CLONE);
00182         for (j = 0; j < ncopies; j++) {
00183             pixt = pixCopy(NULL, pix);
00184             pixaAddPix(pixa, pixt, L_INSERT);
00185         }
00186         pixDestroy(&pix);
00187     }
00188     pixaaDestroy(&paa);
00189 
00190     return;
00191 }
00192 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines