Skip to content

Commit fbc878c

Browse files
committed
Bug#25418534: JSON_EXTRACT USING WILDCARDS TAKES FOREVER
Patch #0: Add microbenchmarks that measure the performance of Json_wrapper::seek(). Change-Id: I1a5990eea93667c9119f1637701852bd752fc896
1 parent e3c1120 commit fbc878c

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

unittest/gunit/json_dom-t.cc

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "base64.h"
2121
#include "base_mock_field.h"
22+
#include "benchmark.h"
2223
#include "fake_table.h"
2324
#include "json_binary.h"
2425
#include "json_diff.h"
@@ -1294,4 +1295,139 @@ TEST_F(JsonDomTest, ApplyJsonDiffs_CollectBinaryDiffs)
12941295
do_apply_json_diffs_tests(&m_field);
12951296
}
12961297

1298+
/**
1299+
Run a microbenchmarks that tests how fast Json_wrapper::seek() is on
1300+
a wrapper that wraps a Json_dom.
1301+
1302+
@param num_iterations the number of iterations to run
1303+
@param path the JSON path to search for
1304+
@param need_only_one true if the search should stop after the first match
1305+
@param expected_hits the number of expected matches
1306+
*/
1307+
static void benchmark_dom_seek(size_t num_iterations, const Json_path &path,
1308+
bool need_only_one, size_t expected_matches)
1309+
{
1310+
StopBenchmarkTiming();
1311+
1312+
Json_object o;
1313+
for (size_t i= 0; i < 1000; ++i)
1314+
o.add_alias(std::to_string(i), new (std::nothrow) Json_object());
1315+
1316+
Json_wrapper wr(&o);
1317+
wr.set_alias();
1318+
1319+
StartBenchmarkTiming();
1320+
1321+
for (size_t i= 0; i < num_iterations; ++i)
1322+
{
1323+
Json_wrapper_vector hits(PSI_NOT_INSTRUMENTED);
1324+
wr.seek(path, &hits, true, need_only_one);
1325+
EXPECT_EQ(expected_matches, hits.size());
1326+
}
1327+
1328+
StopBenchmarkTiming();
1329+
}
1330+
1331+
/**
1332+
Microbenchmark which tests how fast a lookup with an ellipsis is in
1333+
a wrapper that wraps a Json_dom.
1334+
*/
1335+
static void BM_JsonDomSearchEllipsis(size_t num_iterations)
1336+
{
1337+
benchmark_dom_seek(num_iterations, parse_path("$**.\"432\""), false, 1);
1338+
}
1339+
BENCHMARK(BM_JsonDomSearchEllipsis);
1340+
1341+
/**
1342+
Microbenchmark which tests how fast a lookup with an ellipsis is in
1343+
a wrapper that wraps a Json_dom, with the `need_only_one` flag set.
1344+
*/
1345+
static void BM_JsonDomSearchEllipsis_OnlyOne(size_t num_iterations)
1346+
{
1347+
benchmark_dom_seek(num_iterations, parse_path("$**.\"432\""), true, 1);
1348+
}
1349+
BENCHMARK(BM_JsonDomSearchEllipsis_OnlyOne);
1350+
1351+
/**
1352+
Microbenchmark which tests how fast a lookup of a JSON object member
1353+
is in a wrapper that wraps a Json_dom.
1354+
*/
1355+
static void BM_JsonDomSearchKey(size_t num_iterations)
1356+
{
1357+
benchmark_dom_seek(num_iterations, parse_path("$.\"432\""), false, 1);
1358+
}
1359+
BENCHMARK(BM_JsonDomSearchKey);
1360+
1361+
/**
1362+
Run a microbenchmarks that tests how fast Json_wrapper::seek() is on
1363+
a wrapper that wraps a binary JSON value.
1364+
1365+
@param num_iterations the number of iterations to run
1366+
@param path the JSON path to search for
1367+
@param need_only_one true if the search should stop after the first match
1368+
@param expected_hits the number of expected matches
1369+
*/
1370+
static void benchmark_binary_seek(size_t num_iterations, const Json_path &path,
1371+
bool need_only_one, size_t expected_matches)
1372+
{
1373+
StopBenchmarkTiming();
1374+
1375+
Json_object o;
1376+
for (size_t i= 0; i < 1000; ++i)
1377+
o.add_alias(std::to_string(i), new (std::nothrow) Json_object());
1378+
1379+
my_testing::Server_initializer initializer;
1380+
initializer.SetUp();
1381+
1382+
String buffer;
1383+
EXPECT_FALSE(json_binary::serialize(initializer.thd(), &o, &buffer));
1384+
json_binary::Value val=
1385+
json_binary::parse_binary(buffer.ptr(), buffer.length());
1386+
1387+
StartBenchmarkTiming();
1388+
1389+
for (size_t i= 0; i < num_iterations; ++i)
1390+
{
1391+
Json_wrapper wr(val);
1392+
Json_wrapper_vector hits(PSI_NOT_INSTRUMENTED);
1393+
wr.seek(path, &hits, true, need_only_one);
1394+
EXPECT_EQ(expected_matches, hits.size());
1395+
}
1396+
1397+
StopBenchmarkTiming();
1398+
1399+
initializer.TearDown();
1400+
}
1401+
1402+
/**
1403+
Microbenchmark which tests how fast a lookup with an ellipsis is in
1404+
a Json_wrapper which wraps a binary JSON value.
1405+
*/
1406+
static void BM_JsonBinarySearchEllipsis(size_t num_iterations)
1407+
{
1408+
benchmark_binary_seek(num_iterations, parse_path("$**.\"432\""), false, 1);
1409+
}
1410+
BENCHMARK(BM_JsonBinarySearchEllipsis);
1411+
1412+
/**
1413+
Microbenchmark which tests how fast a lookup with an ellipsis is in
1414+
a Json_wrapper which wraps a binary JSON value, with the `need_only_one`
1415+
flag set.
1416+
*/
1417+
static void BM_JsonBinarySearchEllipsis_OnlyOne(size_t num_iterations)
1418+
{
1419+
benchmark_binary_seek(num_iterations, parse_path("$**.\"432\""), true, 1);
1420+
}
1421+
BENCHMARK(BM_JsonBinarySearchEllipsis_OnlyOne);
1422+
1423+
/**
1424+
Microbenchmark which tests how fast a lookup of a JSON object member
1425+
is in a Json_wrapper which wraps a binary JSON value.
1426+
*/
1427+
static void BM_JsonBinarySearchKey(size_t num_iterations)
1428+
{
1429+
benchmark_binary_seek(num_iterations, parse_path("$.\"432\""), false, 1);
1430+
}
1431+
BENCHMARK(BM_JsonBinarySearchKey);
1432+
12971433
} // namespace

0 commit comments

Comments
 (0)