1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-06 23:49:25 +03:00

added gettimeofday() check profiling works option --profile (or --norman

* config.h.in configure.in: added gettimeofday() check
* libxslt/transform.c libxslt/xsltInternals.h libxslt/xsltutils.[ch]:
  profiling works option --profile (or --norman ;)
Daniel
This commit is contained in:
Daniel Veillard
2001-07-07 21:24:06 +00:00
parent 6744bd096b
commit a48ce8ba9d
8 changed files with 142 additions and 33 deletions

View File

@@ -1,3 +1,9 @@
Sat Jul 7 23:19:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* config.h.in configure.in: added gettimeofday() check
* libxslt/transform.c libxslt/xsltInternals.h libxslt/xsltutils.[ch]:
profiling works option --profile (or --norman ;)
Sat Jul 7 18:58:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr> Sat Jul 7 18:58:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/templates.c libxslt/transform.c libxslt/transform.h * libxslt/templates.c libxslt/transform.c libxslt/transform.h

View File

@@ -12,6 +12,9 @@
#undef HAVE_FLOOR #undef HAVE_FLOOR
#undef HAVE_FABS #undef HAVE_FABS
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the <ansidecl.h> header file. */ /* Define if you have the <ansidecl.h> header file. */
#undef HAVE_ANSIDECL_H #undef HAVE_ANSIDECL_H

View File

@@ -52,6 +52,7 @@ AC_CHECK_FUNC(floor, , AC_CHECK_LIB(m, pow,
AC_CHECK_FUNC(fabs, , AC_CHECK_LIB(m, pow, AC_CHECK_FUNC(fabs, , AC_CHECK_LIB(m, pow,
[M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)])) [M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)]))
AC_CHECK_FUNCS(gettimeofday)
dnl dnl
dnl Perl is just needed for generating some data for XSLtmark dnl Perl is just needed for generating some data for XSLtmark

View File

@@ -73,6 +73,16 @@ int xsltMaxDepth = 500;
#define PUSH_AND_POP(scope, type, name) \ #define PUSH_AND_POP(scope, type, name) \
scope int name##Push(xsltTransformContextPtr ctxt, type value) { \ scope int name##Push(xsltTransformContextPtr ctxt, type value) { \
if (ctxt->name##Max == 0) { \
ctxt->name##Max = 4; \
ctxt->name##Tab = (type *) xmlMalloc(ctxt->name##Max * \
sizeof(ctxt->name##Tab[0])); \
if (ctxt->name##Tab == NULL) { \
xmlGenericError(xmlGenericErrorContext, \
"malloc failed !\n"); \
return(0); \
} \
} \
if (ctxt->name##Nr >= ctxt->name##Max) { \ if (ctxt->name##Nr >= ctxt->name##Max) { \
ctxt->name##Max *= 2; \ ctxt->name##Max *= 2; \
ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \ ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
@@ -94,7 +104,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
if (ctxt->name##Nr > 0) \ if (ctxt->name##Nr > 0) \
ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
else \ else \
ctxt->name = NULL; \ ctxt->name = (type) 0; \
ret = ctxt->name##Tab[ctxt->name##Nr]; \ ret = ctxt->name##Tab[ctxt->name##Nr]; \
ctxt->name##Tab[ctxt->name##Nr] = 0; \ ctxt->name##Tab[ctxt->name##Nr] = 0; \
return(ret); \ return(ret); \
@@ -105,6 +115,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
*/ */
PUSH_AND_POP(static, xsltTemplatePtr, templ) PUSH_AND_POP(static, xsltTemplatePtr, templ)
PUSH_AND_POP(static, xsltStackElemPtr, vars) PUSH_AND_POP(static, xsltStackElemPtr, vars)
PUSH_AND_POP(static, long, prof)
/************************************************************************ /************************************************************************
* * * *
@@ -196,6 +207,13 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->varsMax = 5; cur->varsMax = 5;
cur->vars = NULL; cur->vars = NULL;
cur->varsBase = 0; cur->varsBase = 0;
/*
* the profiling stcka is not initialized by default
*/
cur->profTab = NULL;
cur->profNr = 0;
cur->profMax = 0;
cur->prof = 0;
cur->style = style; cur->style = style;
xmlXPathInit(); xmlXPathInit();
@@ -968,6 +986,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldInst = NULL; xmlNodePtr oldInst = NULL;
xmlAttrPtr attrs; xmlAttrPtr attrs;
int oldBase; int oldBase;
long start = 0;
if ((ctxt == NULL) || (list == NULL)) if ((ctxt == NULL) || (list == NULL))
return; return;
@@ -983,7 +1002,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
/* /*
* stack and saves * stack saves, beware ordering of operations counts
*/ */
oldInsert = insert = ctxt->insert; oldInsert = insert = ctxt->insert;
oldInst = ctxt->inst; oldInst = ctxt->inst;
@@ -995,6 +1014,8 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
ctxt->node = node; ctxt->node = node;
if (ctxt->profile) { if (ctxt->profile) {
templ->nbCalls++; templ->nbCalls++;
start = xsltTimestamp();
profPush(ctxt, 0);
} }
templPush(ctxt, templ); templPush(ctxt, templ);
#ifdef WITH_XSLT_DEBUG_PROCESS #ifdef WITH_XSLT_DEBUG_PROCESS
@@ -1019,30 +1040,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: insert == NULL !\n"); "xsltApplyOneTemplate: insert == NULL !\n");
#endif #endif
ctxt->node = oldCurrent; goto error;
ctxt->inst = oldInst;
ctxt->insert = oldInsert;
if (params == NULL)
xsltFreeStackElemList(varsPop(ctxt));
else {
xsltStackElemPtr p, tmp = varsPop(ctxt);
if (tmp != params) {
p = tmp;
while ((p != NULL) && (p->next != params))
p = p->next;
if (p == NULL) {
xsltFreeStackElemList(tmp);
} else {
p->next = NULL;
xsltFreeStackElemList(tmp);
}
}
}
if (templ != NULL) {
ctxt->varsBase = oldBase;
templPop(ctxt);
}
return;
} }
if (IS_XSLT_ELEM(cur)) { if (IS_XSLT_ELEM(cur)) {
@@ -1202,6 +1200,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
} while (cur != NULL); } while (cur != NULL);
} }
error:
ctxt->node = oldCurrent; ctxt->node = oldCurrent;
ctxt->inst = oldInst; ctxt->inst = oldInst;
ctxt->insert = oldInsert; ctxt->insert = oldInsert;
@@ -1224,6 +1223,18 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (templ != NULL) { if (templ != NULL) {
ctxt->varsBase = oldBase; ctxt->varsBase = oldBase;
templPop(ctxt); templPop(ctxt);
if (ctxt->profile) {
long spent, child, total, end;
end = xsltTimestamp();
child = profPop(ctxt);
total = end - start;
spent = total - child;
templ->time += spent;
if (ctxt->profNr > 0)
ctxt->profTab[ctxt->profNr - 1] += total;
}
} }
} }

View File

@@ -385,6 +385,10 @@ struct _xsltTransformContext {
const char * outputFile; /* the output URI if known */ const char * outputFile; /* the output URI if known */
int profile; /* is this run profiled */ int profile; /* is this run profiled */
long prof; /* the current profiled value */
int profNr; /* Nb of templates in the stack */
int profMax; /* Size of the templtaes stack */
long *profTab; /* the profile template stack */
}; };
/** /**

View File

@@ -114,7 +114,7 @@ static void usage(const char *name) {
#ifdef LIBXML_XINCLUDE_ENABLED #ifdef LIBXML_XINCLUDE_ENABLED
printf(" --xinclude : do XInclude processing on document intput\n"); printf(" --xinclude : do XInclude processing on document intput\n");
#endif #endif
printf(" --profile : dump profiling informations \n"); printf(" --profile or --norman : dump profiling informations \n");
} }
int int
@@ -192,6 +192,9 @@ main(int argc, char **argv)
} else if ((!strcmp(argv[i], "-profile")) || } else if ((!strcmp(argv[i], "-profile")) ||
(!strcmp(argv[i], "--profile"))) { (!strcmp(argv[i], "--profile"))) {
profile++; profile++;
} else if ((!strcmp(argv[i], "-norman")) ||
(!strcmp(argv[i], "--norman"))) {
profile++;
} else if ((!strcmp(argv[i], "-warnnet")) || } else if ((!strcmp(argv[i], "-warnnet")) ||
(!strcmp(argv[i], "--warnnet"))) { (!strcmp(argv[i], "--warnnet"))) {
xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader); xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader);

View File

@@ -12,6 +12,15 @@
#include "libxslt.h" #include "libxslt.h"
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <libxml/xmlmemory.h> #include <libxml/xmlmemory.h>
@@ -24,6 +33,16 @@
#include "xsltInternals.h" #include "xsltInternals.h"
#include "imports.h" #include "imports.h"
/* gettimeofday on Windows ??? */
#ifdef WIN32
#ifdef _MSC_VER
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define gettimeofday(p1,p2)
#define HAVE_GETTIMEOFDAY
#endif /* _MS_VER */
#endif /* WIN32 */
/************************************************************************ /************************************************************************
* * * *
* Convenience function * * Convenience function *
@@ -941,10 +960,63 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {
/************************************************************************ /************************************************************************
* * * *
* Generating proviling output * * Generating profiling informations *
* * * *
************************************************************************/ ************************************************************************/
/**
* xsltCalibrateTimestamps:
*
* Used for to calibrate the xsltTimestamp() function
* Should work if launched at startup and we don't loose our quantum :-)
*
* Returns the number of milliseconds used by xsltTimestamp()
*/
static long
xsltCalibrateTimestamps(void) {
register int i;
for (i = 0;i < 999;i++)
xsltTimestamp();
return(xsltTimestamp() / 1000);
}
/**
* xsltTimestamp:
*
* Used for gathering profiling data
*
* Returns the number of milliseconds since the beginning of the
* profiling
*/
long
xsltTimestamp(void) {
#ifdef HAVE_GETTIMEOFDAY
static long calibration = -1;
static struct timeval startup;
struct timeval cur;
long msec;
if (calibration == -1) {
gettimeofday(&startup, NULL);
calibration = 0;
calibration = xsltCalibrateTimestamps();
gettimeofday(&startup, NULL);
return(0);
}
gettimeofday(&cur, NULL);
msec = cur.tv_sec - startup.tv_sec;
msec *= 10000;
msec += (cur.tv_usec - startup.tv_usec) / 100;
msec -= calibration;
return((unsigned long) msec);
#else
return(0);
#endif
}
#define MAX_TEMPLATES 10000 #define MAX_TEMPLATES 10000
/** /**
@@ -959,6 +1031,7 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
int nb, i,j; int nb, i,j;
int max; int max;
int total; int total;
long totalt;
xsltTemplatePtr *templates; xsltTemplatePtr *templates;
xsltStylesheetPtr style; xsltStylesheetPtr style;
xsltTemplatePtr template; xsltTemplatePtr template;
@@ -981,6 +1054,7 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
if (nb >= max) if (nb >= max)
break; break;
if (template->nbCalls > 0)
templates[nb++] = template; templates[nb++] = template;
template = template->next; template = template->next;
} }
@@ -990,7 +1064,9 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
for (i = 0;i < nb -1;i++) { for (i = 0;i < nb -1;i++) {
for (j = i + 1; j < nb; j++) { for (j = i + 1; j < nb; j++) {
if (templates[i]->nbCalls <= templates[j]->nbCalls) { if ((templates[i]->time <= templates[j]->time) ||
((templates[i]->time == templates[j]->time) &&
(templates[i]->nbCalls <= templates[j]->nbCalls))) {
template = templates[j]; template = templates[j];
templates[j] = templates[i]; templates[j] = templates[i];
templates[i] = template; templates[i] = template;
@@ -998,9 +1074,10 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
} }
} }
fprintf(output, "%6s%20s%20s%10s NbCalls\n\n", fprintf(output, "%6s%20s%20s%10s NbCalls Time 100us\n\n",
"number", "match", "name", "mode"); "number", "match", "name", "mode");
total = 0; total = 0;
totalt = 0;
for (i = 0;i < nb;i++) { for (i = 0;i < nb;i++) {
fprintf(output, "%5d ", i); fprintf(output, "%5d ", i);
if (templates[i]->match != NULL) { if (templates[i]->match != NULL) {
@@ -1027,10 +1104,12 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
} else { } else {
fprintf(output, "%10s", ""); fprintf(output, "%10s", "");
} }
fprintf(output, " %6d\n", templates[i]->nbCalls); fprintf(output, " %6d", templates[i]->nbCalls);
fprintf(output, " %6ld\n", templates[i]->time);
total += templates[i]->nbCalls; total += templates[i]->nbCalls;
totalt += templates[i]->time;
} }
fprintf(output, "\n%30s%26s %6d\n", "Total", "", total); fprintf(output, "\n%30s%26s %6d %6ld\n", "Total", "", total, totalt);
xmlFree(templates); xmlFree(templates);
} }

View File

@@ -116,6 +116,8 @@ int xsltSaveResultToFd (int fd,
void xsltSaveProfiling (xsltTransformContextPtr ctxt, void xsltSaveProfiling (xsltTransformContextPtr ctxt,
FILE *output); FILE *output);
long xsltTimestamp (void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif