Line data Source code
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 4 : 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 4 : int use_inc = 0; 45 : 46 4 : pg_logging_init(argv[0]); 47 : 48 4 : initStringInfo(&json); 49 : 50 4 : if (strcmp(argv[1], "-i") == 0) 51 : { 52 2 : use_inc = 1; 53 2 : argv++; 54 : } 55 : 56 4 : sscanf(argv[1], "%d", &iter); 57 : 58 4 : if ((json_file = fopen(argv[2], PG_BINARY_R)) == NULL) 59 0 : pg_fatal("Could not open input file '%s': %m", argv[2]); 60 : 61 4 : while ((n_read = fread(buff, 1, 6000, json_file)) > 0) 62 : { 63 0 : appendBinaryStringInfo(&json, buff, n_read); 64 : } 65 4 : fclose(json_file); 66 4 : for (int i = 0; i < iter; i++) 67 : { 68 4 : if (use_inc) 69 : { 70 2 : lex = makeJsonLexContextIncremental(NULL, PG_UTF8, false); 71 2 : result = pg_parse_json_incremental(lex, &nullSemAction, 72 2 : json.data, json.len, 73 : true); 74 2 : freeJsonLexContext(lex); 75 : } 76 : else 77 : { 78 2 : lex = makeJsonLexContextCstringLen(NULL, json.data, json.len, 79 : PG_UTF8, false); 80 2 : result = pg_parse_json(lex, &nullSemAction); 81 2 : freeJsonLexContext(lex); 82 : } 83 4 : if (result != JSON_SUCCESS) 84 4 : pg_fatal("unexpected result %d (expecting %d) on parse", 85 : result, JSON_SUCCESS); 86 : } 87 0 : exit(0); 88 : }