]> granicus.if.org Git - postgis/commitdiff
Renamed lwgeom_npoints_recursive to lwgeom_npoints and exposed in lwgeom.h.
authorSandro Santilli <strk@keybit.net>
Wed, 22 Sep 2004 11:42:45 +0000 (11:42 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 22 Sep 2004 11:42:45 +0000 (11:42 +0000)
Changed SERIALIZED_FORM macro to be less LWGEOM structure aware.
Added profiling header file.
Modified profiling calls to include total query time.
Initial profiling support in the mindistance function.

git-svn-id: http://svn.osgeo.org/postgis/trunk@872 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom.h
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_geos.c
lwgeom/profile.h [new file with mode: 0644]

index 49da2ee174bb7b2dd4e9c9981518f5698aa2ff40..e98e302bdd25bbff9ebf18fbf333d880f0448109 100644 (file)
@@ -229,7 +229,7 @@ typedef struct {
  * by most functions from an LWGEOM struct.
  * (which is an LWGEOM w/out int32 size casted to char *)
  */
-#define SERIALIZED_FORM(x) ((char *)&((x)->type))
+#define SERIALIZED_FORM(x) ((char *)(x))+4
 
 
 extern bool lwgeom_hasSRID(unsigned char type); // true iff S bit is set
@@ -790,3 +790,4 @@ void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, doub
 void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
 int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
 POINTARRAY *segmentize2d_ptarray(POINTARRAY *ipa, double dist);
+int32 lwgeom_npoints(char *serialized);
index 1b6574fc5ae18e2a5c12a005513ad03c090f67ec..033fce1495f5fbc7e16ec8a209cf6d443f5d8282 100644 (file)
@@ -11,6 +11,7 @@
 #include "utils/array.h"
 
 #include "lwgeom.h"
+#include "profile.h"
 
 //#define DEBUG
 
@@ -46,7 +47,6 @@ Datum LWGEOM_segmentize2d(PG_FUNCTION_ARGS);
 
 // internal
 char * lwgeom_summary_recursive(char *serialized, int offset);
-int32 lwgeom_npoints_recursive(char *serialized);
 int32 lwgeom_nrings_recursive(char *serialized);
 void dump_lwexploded(LWGEOM_EXPLODED *exploded);
 
@@ -994,7 +994,7 @@ Datum postgis_uses_stats(PG_FUNCTION_ARGS)
  * Recursively count points in a SERIALIZED lwgeom
  */
 int32
-lwgeom_npoints_recursive(char *serialized)
+lwgeom_npoints(char *serialized)
 {
        LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
        int i, j;
@@ -1035,7 +1035,7 @@ lwgeom_npoints_recursive(char *serialized)
                subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
                if ( subgeom != NULL )
                {
-                       npoints += lwgeom_npoints_recursive(subgeom);
+                       npoints += lwgeom_npoints(subgeom);
                }
                else
                {
@@ -1091,7 +1091,7 @@ Datum LWGEOM_npoints(PG_FUNCTION_ARGS)
        LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
        int32 npoints = 0;
 
-       npoints = lwgeom_npoints_recursive(SERIALIZED_FORM(geom));
+       npoints = lwgeom_npoints(SERIALIZED_FORM(geom));
 
        PG_RETURN_INT32(npoints);
 }
@@ -1934,11 +1934,17 @@ Datum LWGEOM_force_multi(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(LWGEOM_mindistance2d);
 Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS)
 {
-
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        double mindist;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        if (lwgeom_getSRID(geom1) != lwgeom_getSRID(geom2))
        {
                elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
@@ -1948,6 +1954,11 @@ Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS)
        mindist = lwgeom_mindistance2d_recursive(SERIALIZED_FORM(geom1),
                SERIALIZED_FORM(geom2));
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_FLOAT8(mindist);
 }
 
index e250043942d78622f55703676db038ee6a279fc2..4af93d21708e618427f8ebba52b8516c6acae9ea 100644 (file)
@@ -4,6 +4,7 @@
 #include "utils/builtins.h"
 
 #include "lwgeom.h"
+#include "profile.h"
 #include "wktparse.h"
 
 Datum relate_full(PG_FUNCTION_ARGS);
@@ -44,41 +45,6 @@ Datum centroid(PG_FUNCTION_ARGS);
 #undef DEBUG_POSTGIS2GEOS
 #undef DEBUG_GEOS2POSTGIS
 
-/*
- * Define this to have profiling enabled
- */
-#define PROFILE
-
-#ifdef PROFILE
-#include <sys/time.h>
-#define PROF_P2G 0
-#define PROF_G2P 1
-#define PROF_GRUN 2
-struct timeval profstart, profstop;
-long proftime[3];
-long profipts, profopts;
-#define profstart(x) do { gettimeofday(&profstart, NULL); } while (0);
-#define profstop(x) do { gettimeofday(&profstop, NULL); \
-       proftime[x] = ( profstop.tv_sec*1000000+profstop.tv_usec) - \
-               ( profstart.tv_sec*1000000+profstart.tv_usec); \
-       } while (0);
-#define profreport(x) do { \
-       long int conv = proftime[PROF_P2G]+proftime[PROF_G2P]; \
-       long int run = proftime[PROF_GRUN]; \
-       long int tot = conv + run; \
-       int convpercent = (((double)conv/(double)tot)*100); \
-       int runpercent = (((double)run/(double)tot)*100); \
-       elog(NOTICE, "PROF_DET: npts:%lu+%lu=%lu cnv:%lu+%lu run:%lu", \
-               profipts, profopts, profipts+profopts, \
-               proftime[PROF_P2G], proftime[PROF_G2P], \
-               proftime[PROF_GRUN]); \
-       elog(NOTICE, "PROF_SUM: pts %lu cnv %d%% run %d%%", \
-               profipts+profopts, \
-               convpercent, \
-               runpercent); \
-       } while (0);
-#endif
-
 typedef  struct Geometry Geometry;
 
 extern const char * createGEOSPoint(POINT3D *pt);
@@ -262,19 +228,33 @@ Datum unite_garray(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(geomunion);
 Datum geomunion(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-       int is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
-               ( lwgeom_ndims(geom2->type) > 2 );
-
+       LWGEOM *geom1;
+       LWGEOM *geom2;
+       int is3d;
        Geometry *g1,*g2,*g3;
        LWGEOM *result;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+       is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
+               ( lwgeom_ndims(geom2->type) > 2 );
+
        initGEOS(MAXIMUM_ALIGNOF);
 //elog(NOTICE,"in geomunion");
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom1);
        g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 //elog(NOTICE,"g1=%s",GEOSasText(g1));
 //elog(NOTICE,"g2=%s",GEOSasText(g2));
@@ -288,8 +268,10 @@ Datum geomunion(PG_FUNCTION_ARGS)
 
 //elog(NOTICE,"g3=%s",GEOSasText(g3));
 
+#ifndef PROFILE
        PG_FREE_IF_COPY(geom1, 0);
        PG_FREE_IF_COPY(geom2, 1);
+#endif
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
 
@@ -301,7 +283,13 @@ Datum geomunion(PG_FUNCTION_ARGS)
 
 //elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, is3d);
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
 
        GEOSdeleteGeometry(g3);
 
@@ -312,6 +300,12 @@ Datum geomunion(PG_FUNCTION_ARGS)
        }
 
        //compressType(result);  // convert multi* to single item if appropriate
+
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, result);
+#endif
+
        PG_RETURN_POINTER(result);
 }
 
@@ -320,19 +314,40 @@ Datum geomunion(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(symdifference);
 Datum symdifference(PG_FUNCTION_ARGS)
 {
-       LWGEOM  *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM  *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2,*g3;
        LWGEOM *result;
-       int is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
+       int is3d;
+
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+       is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
                ( lwgeom_ndims(geom2->type) > 2 );
 
-               initGEOS(MAXIMUM_ALIGNOF);
+       initGEOS(MAXIMUM_ALIGNOF);
+
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
-               g1 =    POSTGIS2GEOS(geom1 );
-               g2 =    POSTGIS2GEOS(geom2 );
-               g3 =    GEOSSymDifference(g1,g2);
+#ifdef PROFILE
+       profstart(PROF_GRUN);
+#endif
+       g3 = GEOSSymDifference(g1,g2);
+#ifdef PROFILE
+       profstop(PROF_GRUN);
+#endif
 
        if (g3 == NULL)
        {
@@ -344,12 +359,13 @@ Datum symdifference(PG_FUNCTION_ARGS)
 
 //     elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+
 #ifdef PROFILE
-       profstart(PROF_GRUN);
+       profstart(PROF_G2P);
 #endif
        result = GEOS2POSTGIS(g3, is3d);
 #ifdef PROFILE
-       profstop(PROF_GRUN);
+       profstop(PROF_G2P);
 #endif
 
        if (result == NULL)
@@ -361,32 +377,48 @@ Datum symdifference(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+       GEOSdeleteGeometry(g1);
+       GEOSdeleteGeometry(g2);
+       GEOSdeleteGeometry(g3);
 
+       //compressType(result);  // convert multi* to single item if appropriate
 
-               GEOSdeleteGeometry(g1);
-               GEOSdeleteGeometry(g2);
-               GEOSdeleteGeometry(g3);
-
-               //compressType(result);  // convert multi* to single item if appropriate
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, result);
+#endif
 
-               PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(result);
 }
 
 
 PG_FUNCTION_INFO_V1(boundary);
 Datum boundary(PG_FUNCTION_ARGS)
 {
-               LWGEOM          *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       LWGEOM  *geom1;
+       Geometry *g1,*g3;
+       LWGEOM *result;
+
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+       initGEOS(MAXIMUM_ALIGNOF);
 
-               Geometry *g1,*g3;
-               LWGEOM *result;
-               initGEOS(MAXIMUM_ALIGNOF);
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
-               g1 =    POSTGIS2GEOS(geom1 );
 #ifdef PROFILE
        profstart(PROF_GRUN);
 #endif
-               g3 =    GEOSBoundary(g1);
+       g3 = GEOSBoundary(g1);
 #ifdef PROFILE
        profstop(PROF_GRUN);
 #endif
@@ -400,7 +432,14 @@ Datum boundary(PG_FUNCTION_ARGS)
 
 //     elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, lwgeom_ndims(geom1->type) > 2);
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+
        if (result == NULL)
        {
                GEOSdeleteGeometry(g1);
@@ -412,26 +451,49 @@ Datum boundary(PG_FUNCTION_ARGS)
 
 
 
-               GEOSdeleteGeometry(g1);
-               GEOSdeleteGeometry(g3);
+       GEOSdeleteGeometry(g1);
+       GEOSdeleteGeometry(g3);
+
+       //compressType(result);  // convert multi* to single item if appropriate
 
-               //compressType(result);  // convert multi* to single item if appropriate
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, NULL, result);
+#endif
 
-               PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(result);
 }
 
 PG_FUNCTION_INFO_V1(convexhull);
 Datum convexhull(PG_FUNCTION_ARGS)
 {
-               LWGEOM          *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-               Geometry *g1,*g3;
-               LWGEOM *result;
+       LWGEOM  *geom1;
+       Geometry *g1,*g3;
+       LWGEOM *result;
 
-               initGEOS(MAXIMUM_ALIGNOF);
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+       initGEOS(MAXIMUM_ALIGNOF);
 
-               g1 =    POSTGIS2GEOS(geom1 );
-               g3 =    GEOSConvexHull(g1);
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
+#ifdef PROFILE
+       profstart(PROF_GRUN);
+#endif
+       g3 = GEOSConvexHull(g1);
+#ifdef PROFILE
+       profstop(PROF_GRUN);
+#endif
 
        if (g3 == NULL)
        {
@@ -455,25 +517,49 @@ Datum convexhull(PG_FUNCTION_ARGS)
                GEOSdeleteGeometry(g3);
 
 
-               //compressType(result);  // convert multi* to single item if appropriate
+       //compressType(result);  // convert multi* to single item if appropriate
 
-               PG_RETURN_POINTER(result);
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, NULL, result);
+#endif
+
+       PG_RETURN_POINTER(result);
 
 }
 
 PG_FUNCTION_INFO_V1(buffer);
 Datum buffer(PG_FUNCTION_ARGS)
 {
-               LWGEOM          *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-               double                  size   = PG_GETARG_FLOAT8(1);
-               Geometry *g1,*g3;
-               LWGEOM *result;
+       LWGEOM  *geom1;
+       double  size;
+       Geometry *g1,*g3;
+       LWGEOM *result;
+
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
 
-               initGEOS(MAXIMUM_ALIGNOF);
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       size = PG_GETARG_FLOAT8(1);
 
-               g1 =    POSTGIS2GEOS(geom1 );
-               g3 =    GEOSBuffer(g1,size);
+       initGEOS(MAXIMUM_ALIGNOF);
+
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
+#ifdef PROFILE
+       profstart(PROF_GRUN);
+#endif
+       g3 = GEOSBuffer(g1,size);
+#ifdef PROFILE
+       profstop(PROF_GRUN);
+#endif
 
        if (g3 == NULL)
        {
@@ -485,7 +571,13 @@ Datum buffer(PG_FUNCTION_ARGS)
 
 //     elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, lwgeom_ndims(geom1->type) > 2);
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
        if (result == NULL)
        {
                GEOSdeleteGeometry(g1);
@@ -493,31 +585,51 @@ Datum buffer(PG_FUNCTION_ARGS)
                elog(ERROR,"GEOS buffer() threw an error (result postgis geometry formation)!");
                PG_RETURN_NULL(); //never get here
        }
-               GEOSdeleteGeometry(g1);
-               GEOSdeleteGeometry(g3);
+       GEOSdeleteGeometry(g1);
+       GEOSdeleteGeometry(g3);
+
 
+       //compressType(result);  // convert multi* to single item if appropriate
 
-               //compressType(result);  // convert multi* to single item if appropriate
-               PG_RETURN_POINTER(result);
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, NULL, result);
+#endif
 
+       PG_RETURN_POINTER(result);
 }
 
 PG_FUNCTION_INFO_V1(intersection);
 Datum intersection(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2,*g3;
        LWGEOM *result;
-       int is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
+       int is3d;
+
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+       is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
                ( lwgeom_ndims(geom2->type) > 2 );
 
        initGEOS(MAXIMUM_ALIGNOF);
 
 //elog(NOTICE,"intersection() START");
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom1);
        g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 //elog(NOTICE,"               constructed geometrys - calling geos");
 
@@ -536,7 +648,7 @@ Datum intersection(PG_FUNCTION_ARGS)
 #ifdef PROFILE
        profstart(PROF_GRUN);
 #endif
-       g3 =   GEOSIntersection(g1,g2);
+       g3 = GEOSIntersection(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
 #endif
@@ -554,7 +666,14 @@ Datum intersection(PG_FUNCTION_ARGS)
 
        //elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, is3d);
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
+
        if (result == NULL)
        {
                GEOSdeleteGeometry(g1);
@@ -566,31 +685,50 @@ Datum intersection(PG_FUNCTION_ARGS)
 
 
 
-               GEOSdeleteGeometry(g1);
-               GEOSdeleteGeometry(g2);
-               GEOSdeleteGeometry(g3);
+       GEOSdeleteGeometry(g1);
+       GEOSdeleteGeometry(g2);
+       GEOSdeleteGeometry(g3);
+
+       //compressType(result);  // convert multi* to single item if appropriate
 
-               //compressType(result);  // convert multi* to single item if appropriate
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, result);
+#endif
 
-               PG_RETURN_POINTER(result);
+       PG_RETURN_POINTER(result);
 }
 
 //select difference('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5))');
 PG_FUNCTION_INFO_V1(difference);
 Datum difference(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2,*g3;
        LWGEOM *result;
-       int is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
+       int is3d;
+
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+       is3d = ( lwgeom_ndims(geom1->type) > 2 ) ||
                ( lwgeom_ndims(geom2->type) > 2 );
 
        initGEOS(MAXIMUM_ALIGNOF);
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom1);
        g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -610,7 +748,13 @@ Datum difference(PG_FUNCTION_ARGS)
 
 //     elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, is3d);
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
        if (result == NULL)
        {
                GEOSdeleteGeometry(g1);
@@ -626,6 +770,11 @@ Datum difference(PG_FUNCTION_ARGS)
 
        ////compressType(result);  // convert multi* to single item if appropriate
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, result);
+#endif
+
        PG_RETURN_POINTER(result);
 }
 
@@ -634,14 +783,25 @@ Datum difference(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(pointonsurface);
 Datum pointonsurface(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-
+       LWGEOM *geom1;
        Geometry *g1,*g3;
        LWGEOM *result;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -658,12 +818,15 @@ Datum pointonsurface(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
-
-
-
 //     elog(NOTICE,"result: %s", GEOSasText(g3) ) ;
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(g3, (lwgeom_ndims(geom1->type) > 2));
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
        if (result == NULL)
        {
                GEOSdeleteGeometry(g1);
@@ -672,14 +835,17 @@ Datum pointonsurface(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
-
-
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g3);
 
        // convert multi* to single item if appropriate
        //compressType(result); 
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, NULL, result);
+#endif
+
        PG_RETURN_POINTER(result);
 }
 
@@ -689,11 +855,21 @@ Datum centroid(PG_FUNCTION_ARGS)
        LWGEOM *geom, *result;
        Geometry *geosgeom, *geosresult;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
        geom = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 
        initGEOS(MAXIMUM_ALIGNOF);
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        geosgeom = POSTGIS2GEOS(geom);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -710,7 +886,13 @@ Datum centroid(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); 
        }
 
+#ifdef PROFILE
+       profstart(PROF_G2P);
+#endif
        result = GEOS2POSTGIS(geosresult, (lwgeom_ndims(geom->type) > 2));
+#ifdef PROFILE
+       profstop(PROF_G2P);
+#endif
        if (result == NULL)
        {
                GEOSdeleteGeometry(geosgeom);
@@ -721,6 +903,11 @@ Datum centroid(PG_FUNCTION_ARGS)
        GEOSdeleteGeometry(geosgeom);
        GEOSdeleteGeometry(geosresult);
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom, NULL, result);
+#endif
+
        PG_RETURN_POINTER(result);
 }
 
@@ -742,13 +929,25 @@ void errorIfGeometryCollection(LWGEOM *g1, LWGEOM *g2)
 PG_FUNCTION_INFO_V1(isvalid);
 Datum isvalid(PG_FUNCTION_ARGS)
 {
-       LWGEOM          *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       LWGEOM  *geom1;
        bool result;
        Geometry *g1;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -756,8 +955,6 @@ Datum isvalid(PG_FUNCTION_ARGS)
        result = GEOSisvalid(g1);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P]=0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -768,6 +965,11 @@ Datum isvalid(PG_FUNCTION_ARGS)
        }
 
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, NULL, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -778,12 +980,19 @@ Datum isvalid(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(overlaps);
 Datum overlaps(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -802,8 +1011,14 @@ Datum overlaps(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 = POSTGIS2GEOS(geom1 );
-       g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -811,8 +1026,6 @@ Datum overlaps(PG_FUNCTION_ARGS)
        result = GEOSrelateOverlaps(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -823,6 +1036,11 @@ Datum overlaps(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -831,12 +1049,19 @@ Datum overlaps(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(contains);
 Datum contains(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -855,8 +1080,14 @@ Datum contains(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
-       g2 =    POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -864,8 +1095,6 @@ Datum contains(PG_FUNCTION_ARGS)
        result = GEOSrelateContains(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -877,6 +1106,11 @@ Datum contains(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -884,12 +1118,19 @@ Datum contains(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(within);
 Datum within(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -908,8 +1149,14 @@ Datum within(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
-       g2 =    POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -917,8 +1164,6 @@ Datum within(PG_FUNCTION_ARGS)
        result = GEOSrelateWithin(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -930,6 +1175,11 @@ Datum within(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -938,12 +1188,19 @@ Datum within(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(crosses);
 Datum crosses(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -962,8 +1219,14 @@ Datum crosses(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
-       g2 =    POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -971,8 +1234,6 @@ Datum crosses(PG_FUNCTION_ARGS)
        result = GEOSrelateCrosses(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -984,6 +1245,11 @@ Datum crosses(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -992,12 +1258,19 @@ Datum crosses(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(intersects);
 Datum intersects(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -1016,8 +1289,14 @@ Datum intersects(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 =    POSTGIS2GEOS(geom1 );
-       g2 =    POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1 );
+       g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1025,8 +1304,6 @@ Datum intersects(PG_FUNCTION_ARGS)
        result = GEOSrelateIntersects(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
@@ -1036,6 +1313,11 @@ Datum intersects(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -1043,12 +1325,19 @@ Datum intersects(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(touches);
 Datum touches(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -1067,8 +1356,14 @@ Datum touches(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom1 );
        g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1076,8 +1371,6 @@ Datum touches(PG_FUNCTION_ARGS)
        result = GEOSrelateTouches(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
        GEOSdeleteGeometry(g1);
@@ -1089,6 +1382,11 @@ Datum touches(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -1096,12 +1394,19 @@ Datum touches(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(disjoint);
 Datum disjoint(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -1120,8 +1425,14 @@ Datum disjoint(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 = POSTGIS2GEOS(geom1 );
-       g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1129,8 +1440,6 @@ Datum disjoint(PG_FUNCTION_ARGS)
        result = GEOSrelateDisjoint(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
@@ -1141,6 +1450,11 @@ Datum disjoint(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -1148,18 +1462,31 @@ Datum disjoint(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(relate_pattern);
 Datum relate_pattern(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        char *patt;
        bool result;
-
        Geometry *g1,*g2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
+
        initGEOS(MAXIMUM_ALIGNOF);
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom1);
        g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
        patt =  DatumGetCString(DirectFunctionCall1(textout,
                         PointerGetDatum(PG_GETARG_DATUM(2))));
@@ -1170,8 +1497,6 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
        result = GEOSrelatePattern(g1,g2,patt);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
@@ -1183,9 +1508,12 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
-       PG_RETURN_BOOL(result);
-
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
 
+       PG_RETURN_BOOL(result);
 }
 
 
@@ -1193,16 +1521,22 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(relate_full);
 Datum relate_full(PG_FUNCTION_ARGS)
 {
-       LWGEOM          *geom1 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM          *geom2 = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
-       char    *relate_str;
+       char *relate_str;
        int len;
        char *result;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
 //elog(NOTICE,"in relate_full()");
 
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
 
@@ -1210,17 +1544,19 @@ Datum relate_full(PG_FUNCTION_ARGS)
 
 //elog(NOTICE,"GEOS init()");
 
-       g1 =    POSTGIS2GEOS(geom1 );
-       g2 =    POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1 );
+       g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 //elog(NOTICE,"constructed geometries ");
 
-
-
-
-
-if ((g1==NULL) || (g2 == NULL))
-       elog(NOTICE,"g1 or g2 are null");
+       if ((g1==NULL) || (g2 == NULL))
+               elog(NOTICE,"g1 or g2 are null");
 
 //elog(NOTICE,GEOSasText(g1));
 //elog(NOTICE,GEOSasText(g2));
@@ -1234,11 +1570,9 @@ if ((g1==NULL) || (g2 == NULL))
 #ifdef PROFILE
        profstart(PROF_GRUN);
 #endif
-               relate_str = GEOSrelate(g1, g2);
+       relate_str = GEOSrelate(g1, g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
 
 //elog(NOTICE,"finished relate()");
@@ -1246,8 +1580,6 @@ if ((g1==NULL) || (g2 == NULL))
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
 
-
-
        if (relate_str == NULL)
        {
                //free(relate_str);
@@ -1255,7 +1587,6 @@ if ((g1==NULL) || (g2 == NULL))
                PG_RETURN_NULL(); //never get here
        }
 
-
        len = strlen(relate_str) + 4;
 
        result= palloc(len);
@@ -1265,6 +1596,10 @@ if ((g1==NULL) || (g2 == NULL))
 
        free(relate_str);
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
 
        PG_RETURN_POINTER(result);
 }
@@ -1274,12 +1609,19 @@ if ((g1==NULL) || (g2 == NULL))
 PG_FUNCTION_INFO_V1(geomequals);
 Datum geomequals(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       LWGEOM *geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+       LWGEOM *geom1;
+       LWGEOM *geom2;
        Geometry *g1,*g2;
        bool result;
        const BOX2DFLOAT4 *box1, *box2;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom1 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       geom2 = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
        errorIfGeometryCollection(geom1,geom2);
 
        /*
@@ -1298,8 +1640,14 @@ Datum geomequals(PG_FUNCTION_ARGS)
 
        initGEOS(MAXIMUM_ALIGNOF);
 
-       g1 = POSTGIS2GEOS(geom1 );
-       g2 = POSTGIS2GEOS(geom2 );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom1);
+       g2 = POSTGIS2GEOS(geom2);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1307,8 +1655,6 @@ Datum geomequals(PG_FUNCTION_ARGS)
        result = GEOSequals(g1,g2);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
        GEOSdeleteGeometry(g2);
@@ -1319,17 +1665,27 @@ Datum geomequals(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom1, geom2, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
 PG_FUNCTION_INFO_V1(issimple);
 Datum issimple(PG_FUNCTION_ARGS)
 {
-       LWGEOM *geom = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-
+       LWGEOM *geom;
        Geometry *g1;
        int result;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
        if (lwgeom_getnumgeometries(SERIALIZED_FORM(geom)) == 0)
                PG_RETURN_BOOL(true);
 
@@ -1337,7 +1693,13 @@ Datum issimple(PG_FUNCTION_ARGS)
 
        //elog(NOTICE,"GEOS init()");
 
-       g1 = POSTGIS2GEOS(geom );
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
+       g1 = POSTGIS2GEOS(geom);
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1345,8 +1707,6 @@ Datum issimple(PG_FUNCTION_ARGS)
        result = GEOSisSimple(g1);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts=0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
 
@@ -1356,17 +1716,27 @@ Datum issimple(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom, NULL, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
 PG_FUNCTION_INFO_V1(isring);
 Datum isring(PG_FUNCTION_ARGS)
 {
-       LWGEOM  *geom = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-
+       LWGEOM*geom;
        Geometry *g1;
        int result;
 
+#ifdef PROFILE
+       profstart(PROF_QRUN);
+#endif
+
+       geom = (LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
        if (lwgeom_getType(geom->type) != LINETYPE)
        {
                elog(ERROR,"isring() should only be called on a LINE");
@@ -1379,7 +1749,13 @@ Datum isring(PG_FUNCTION_ARGS)
 
        //elog(NOTICE,"GEOS init()");
 
+#ifdef PROFILE
+       profstart(PROF_P2G);
+#endif
        g1 = POSTGIS2GEOS(geom );
+#ifdef PROFILE
+       profstop(PROF_P2G);
+#endif
 
 #ifdef PROFILE
        profstart(PROF_GRUN);
@@ -1387,8 +1763,6 @@ Datum isring(PG_FUNCTION_ARGS)
        result = GEOSisRing(g1);
 #ifdef PROFILE
        profstop(PROF_GRUN);
-       proftime[PROF_G2P] = 0; profopts = 0;
-       profreport();
 #endif
        GEOSdeleteGeometry(g1);
 
@@ -1398,6 +1772,11 @@ Datum isring(PG_FUNCTION_ARGS)
                PG_RETURN_NULL(); //never get here
        }
 
+#ifdef PROFILE
+       profstop(PROF_QRUN);
+       profreport(geom, NULL, NULL);
+#endif
+
        PG_RETURN_BOOL(result);
 }
 
@@ -1638,13 +2017,11 @@ GEOS2POSTGIS(Geometry *geom, char want3d)
 {
        LWGEOM *result;
        LWGEOM_EXPLODED *oexp;
-       int SRID = GEOSGetSRID(geom);
+       int SRID;
        int wantbbox = 0; // might as well be 1 ...
        int size;
 
-#ifdef PROFILE
-       profstart(PROF_G2P);
-#endif
+       SRID = GEOSGetSRID(geom);
 
        // Initialize exploded lwgeom
        oexp = (LWGEOM_EXPLODED *)palloc(sizeof(LWGEOM_EXPLODED));
@@ -1665,12 +2042,6 @@ GEOS2POSTGIS(Geometry *geom, char want3d)
        result->size = size;
        lwexploded_serialize_buf(oexp, wantbbox, SERIALIZED_FORM(result), NULL);
 
-#ifdef PROFILE
-       profstop(PROF_G2P);
-       profopts = lwgeom_npoints_recursive(SERIALIZED_FORM(result));
-       profreport();
-#endif
-
        return result;
 }
 
@@ -1689,11 +2060,6 @@ POSTGIS2GEOS(LWGEOM *geom)
        int ncollected;
        Geometry *ret=NULL;
 
-#ifdef PROFILE
-       profipts = lwgeom_npoints_recursive(SERIALIZED_FORM(geom));
-       profstart(PROF_P2G);
-#endif
-
        type = lwgeom_getType(geom->type);
 
        switch (type)
@@ -1728,9 +2094,6 @@ POSTGIS2GEOS(LWGEOM *geom)
 
        if ( ret )
        {
-#ifdef PROFILE
-               profstop(PROF_P2G);
-#endif
                return ret;
        }
 
@@ -1773,10 +2136,6 @@ POSTGIS2GEOS(LWGEOM *geom)
        ret = PostGIS2GEOS_collection(collected, ncollected,
                exploded->SRID, exploded->ndims > 2);
 
-#ifdef PROFILE
-       profstop(PROF_P2G);
-#endif
-
        return ret;
 
 }
diff --git a/lwgeom/profile.h b/lwgeom/profile.h
new file mode 100644 (file)
index 0000000..815af7d
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _PROFILE_H
+#define _PROFILE_H 1
+
+/*
+ * Define this to have profiling enabled
+ */
+#define PROFILE
+
+#ifdef PROFILE
+#include <sys/time.h>
+#define PROF_P2G 0
+#define PROF_G2P 1
+#define PROF_GRUN 2
+#define PROF_QRUN 3
+struct timeval profstart[4], profstop[4];
+long proftime[4];
+long profipts, profopts;
+#define profstart(x) do { gettimeofday(&(profstart[x]), NULL); } while (0);
+#define profstop(x) do { gettimeofday(&(profstop[x]), NULL); \
+       proftime[x] = ( profstop[x].tv_sec*1000000+profstop[x].tv_usec) - \
+               ( profstart[x].tv_sec*1000000+profstart[x].tv_usec); \
+       } while (0);
+#define profreport(x, y, r) do { \
+       profipts = 0; \
+       if ((x)) profipts += lwgeom_npoints(SERIALIZED_FORM((x))); \
+       if ((y)) profipts += lwgeom_npoints(SERIALIZED_FORM((y))); \
+       if ((r)) profopts = lwgeom_npoints(SERIALIZED_FORM((r))); \
+       else profopts = 0; \
+       long int conv = proftime[PROF_P2G]+proftime[PROF_G2P]; \
+       long int run = proftime[PROF_GRUN]; \
+       long int qrun = proftime[PROF_QRUN]; \
+       long int tot = qrun; \
+       int convpercent = round(((double)conv/(double)tot)*100); \
+       int runpercent = round(((double)run/(double)tot)*100); \
+       elog(NOTICE, \
+               "PROF_DET: npts:%lu+%lu=%lu cnv:%lu+%lu run:%lu gtot:%lu qtot:%lu", \
+               profipts, profopts, profipts+profopts, \
+               proftime[PROF_P2G], proftime[PROF_G2P], \
+               proftime[PROF_GRUN], \
+               proftime[PROF_P2G]+proftime[PROF_G2P]+proftime[PROF_GRUN], \
+               proftime[PROF_QRUN]); \
+       elog(NOTICE, "PROF_SUM: pts %lu cnv %d%% grun %d%% tot %d%%", \
+               profipts+profopts, \
+               convpercent, \
+               runpercent, \
+               convpercent+runpercent); \
+       } while (0);
+#endif // PROFILE
+
+
+#endif // _PROFILE_H