PostgreSQL Source Code git master
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-2025, 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
34int
35main(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);
75 }
76 else
77 {
78 lex = makeJsonLexContextCstringLen(NULL, json.data, json.len,
79 PG_UTF8, false);
80 result = pg_parse_json(lex, &nullSemAction);
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:1232
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
JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)
Definition: jsonapi.c:497
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
Definition: jsonapi.c:744
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
Definition: jsonapi.c:392
const JsonSemAction nullSemAction
Definition: jsonapi.c:287
void freeJsonLexContext(JsonLexContext *lex)
Definition: jsonapi.c:687
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:281
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
int main(int argc, char **argv)
#define BUFSIZE