(root)/
expat-2.5.0/
tests/
benchmark/
benchmark.c
       1  /*
       2                              __  __            _
       3                           ___\ \/ /_ __   __ _| |_
       4                          / _ \\  /| '_ \ / _` | __|
       5                         |  __//  \| |_) | (_| | |_
       6                          \___/_/\_\ .__/ \__,_|\__|
       7                                   |_| XML parser
       8  
       9     Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
      10     Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
      11     Copyright (c) 2017      Sebastian Pipping <sebastian@pipping.org>
      12     Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
      13     Licensed under the MIT license:
      14  
      15     Permission is  hereby granted,  free of charge,  to any  person obtaining
      16     a  copy  of  this  software   and  associated  documentation  files  (the
      17     "Software"),  to  deal in  the  Software  without restriction,  including
      18     without  limitation the  rights  to use,  copy,  modify, merge,  publish,
      19     distribute, sublicense, and/or sell copies of the Software, and to permit
      20     persons  to whom  the Software  is  furnished to  do so,  subject to  the
      21     following conditions:
      22  
      23     The above copyright  notice and this permission notice  shall be included
      24     in all copies or substantial portions of the Software.
      25  
      26     THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
      27     EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
      28     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
      29     NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
      30     DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
      31     OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
      32     USE OR OTHER DEALINGS IN THE SOFTWARE.
      33  */
      34  
      35  #include <sys/stat.h>
      36  #include <stdlib.h>
      37  #include <stdio.h>
      38  #include <time.h>
      39  #include "expat.h"
      40  
      41  #ifdef XML_LARGE_SIZE
      42  #  define XML_FMT_INT_MOD "ll"
      43  #else
      44  #  define XML_FMT_INT_MOD "l"
      45  #endif
      46  
      47  #ifdef XML_UNICODE_WCHAR_T
      48  #  define XML_FMT_STR "ls"
      49  #else
      50  #  define XML_FMT_STR "s"
      51  #endif
      52  
      53  static void
      54  usage(const char *prog, int rc) {
      55    fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
      56    exit(rc);
      57  }
      58  
      59  int
      60  main(int argc, char *argv[]) {
      61    XML_Parser parser;
      62    char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
      63    FILE *fd;
      64    struct stat fileAttr;
      65    int nrOfLoops, bufferSize, fileSize, i, isFinal;
      66    int j = 0, ns = 0;
      67    clock_t tstart, tend;
      68    double cpuTime = 0.0;
      69  
      70    if (argc > 1) {
      71      if (argv[1][0] == '-') {
      72        if (argv[1][1] == 'n' && argv[1][2] == '\0') {
      73          ns = 1;
      74          j = 1;
      75        } else
      76          usage(argv[0], 1);
      77      }
      78    }
      79  
      80    if (argc != j + 4)
      81      usage(argv[0], 1);
      82  
      83    if (stat(argv[j + 1], &fileAttr) != 0) {
      84      fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
      85      return 2;
      86    }
      87  
      88    fd = fopen(argv[j + 1], "r");
      89    if (! fd) {
      90      fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
      91      exit(2);
      92    }
      93  
      94    bufferSize = atoi(argv[j + 2]);
      95    nrOfLoops = atoi(argv[j + 3]);
      96    if (bufferSize <= 0 || nrOfLoops <= 0) {
      97      fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
      98      exit(3);
      99    }
     100  
     101    XMLBuf = malloc(fileAttr.st_size);
     102    fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
     103    fclose(fd);
     104  
     105    if (ns)
     106      parser = XML_ParserCreateNS(NULL, '!');
     107    else
     108      parser = XML_ParserCreate(NULL);
     109  
     110    i = 0;
     111    XMLBufEnd = XMLBuf + fileSize;
     112    while (i < nrOfLoops) {
     113      XMLBufPtr = XMLBuf;
     114      isFinal = 0;
     115      tstart = clock();
     116      do {
     117        int parseBufferSize = XMLBufEnd - XMLBufPtr;
     118        if (parseBufferSize <= bufferSize)
     119          isFinal = 1;
     120        else
     121          parseBufferSize = bufferSize;
     122        if (! XML_Parse(parser, XMLBufPtr, parseBufferSize, isFinal)) {
     123          fprintf(stderr,
     124                  "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
     125                  "u character %" XML_FMT_INT_MOD "u\n",
     126                  XML_ErrorString(XML_GetErrorCode(parser)),
     127                  XML_GetCurrentLineNumber(parser),
     128                  XML_GetCurrentColumnNumber(parser));
     129          free(XMLBuf);
     130          XML_ParserFree(parser);
     131          exit(4);
     132        }
     133        XMLBufPtr += bufferSize;
     134      } while (! isFinal);
     135      tend = clock();
     136      cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
     137      XML_ParserReset(parser, NULL);
     138      i++;
     139    }
     140  
     141    XML_ParserFree(parser);
     142    free(XMLBuf);
     143  
     144    printf("%d loops, with buffer size %d. Average time per loop: %f\n",
     145           nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
     146    return 0;
     147  }