PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test_json_parser_perf.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * test_json_parser_perf.c
4  * Performance test program for both flavors of the JSON parser
5  *
6  * Copyright (c) 2024, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  * src/test/modules/test_json_parser/test_json_parser_perf.c
10  *
11  * This program tests either the standard (recursive descent) JSON parser
12  * or the incremental (table driven) parser, but without breaking the input
13  * into chunks in the latter case. Thus it can be used to compare the pure
14  * parsing speed of the two parsers. If the "-i" option is used, then the
15  * table driven parser is used. Otherwise, the recursive descent parser is
16  * used.
17  *
18  * The remaining arguments are the number of parsing iterations to be done
19  * and the file containing the JSON input.
20  *
21  *-------------------------------------------------------------------------
22  */
23 
24 #include "postgres_fe.h"
25 #include "common/jsonapi.h"
26 #include "common/logging.h"
27 #include "lib/stringinfo.h"
28 #include "mb/pg_wchar.h"
29 #include <stdio.h>
30 #include <string.h>
31 
32 #define BUFSIZE 6000
33 
34 int
35 main(int argc, char **argv)
36 {
37  char buff[BUFSIZE];
38  FILE *json_file;
39  JsonParseErrorType result;
40  JsonLexContext *lex;
41  StringInfoData json;
42  int n_read;
43  int iter;
44  int use_inc = 0;
45 
46  pg_logging_init(argv[0]);
47 
48  initStringInfo(&json);
49 
50  if (strcmp(argv[1], "-i") == 0)
51  {
52  use_inc = 1;
53  argv++;
54  }
55 
56  sscanf(argv[1], "%d", &iter);
57 
58  if ((json_file = fopen(argv[2], PG_BINARY_R)) == NULL)
59  pg_fatal("Could not open input file '%s': %m", argv[2]);
60 
61  while ((n_read = fread(buff, 1, 6000, json_file)) > 0)
62  {
63  appendBinaryStringInfo(&json, buff, n_read);
64  }
65  fclose(json_file);
66  for (int i = 0; i < iter; i++)
67  {
68  if (use_inc)
69  {
70  lex = makeJsonLexContextIncremental(NULL, PG_UTF8, false);
72  json.data, json.len,
73  true);
74  freeJsonLexContext(lex);
75  }
76  else
77  {
78  lex = makeJsonLexContextCstringLen(NULL, json.data, json.len,
79  PG_UTF8, false);
80  result = pg_parse_json(lex, &nullSemAction);
81  freeJsonLexContext(lex);
82  }
83  if (result != JSON_SUCCESS)
84  pg_fatal("unexpected result %d (expecting %d) on parse",
85  result, JSON_SUCCESS);
86  }
87  exit(0);
88 }
#define PG_BINARY_R
Definition: c.h:1254
int i
Definition: isn.c:72
JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)
Definition: jsonapi.c:868
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
Definition: jsonapi.c:744
const JsonSemAction nullSemAction
Definition: jsonapi.c:287
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
Definition: jsonapi.c:392
void freeJsonLexContext(JsonLexContext *lex)
Definition: jsonapi.c:687
JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)
Definition: jsonapi.c:497
JsonParseErrorType
Definition: jsonapi.h:35
@ JSON_SUCCESS
Definition: jsonapi.h:36
exit(1)
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_fatal(...)
@ PG_UTF8
Definition: pg_wchar.h:232
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56
int main(int argc, char **argv)
#define BUFSIZE