{"id":46748,"date":"2023-02-11T00:00:00","date_gmt":"2023-02-11T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/pc-benchmarking-with-griddb\/"},"modified":"2025-11-13T12:56:28","modified_gmt":"2025-11-13T20:56:28","slug":"pc-benchmarking-with-griddb","status":"publish","type":"post","link":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/","title":{"rendered":"PC Benchmarking with GridDB"},"content":{"rendered":"<p>Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In the company&#8217;s case, this would help ensure performance between systems featuring the same components perform consistently, so they could avoid shipping out malfunctioning systems. In the nerd&#8217;s case, it would bring up the pride of having massively over engineered the solution to a non-problem.<\/p>\n<p><a href=\"https:\/\/github.com\/CXWorld\/CapFrameX\">CapFrameX<\/a> is open-source software for Microsoft Windows that can track gaming performance, frames per second (FPS) and frame time, and component sensor data like CPU temperature and graphics card power consumption. When a game is running, CapFrameX can display this data, but it can also save it to a JSON file.<\/p>\n<p>Logging every single frame time, of course, will generate a vast amount of data. The screenshot shows that the current frame took 7.2ms to render, which means we are generating around 150 data points per second, and we want to log all of them. So if we capture 30 minutes of gameplay data, we&#8217;ll have approximately 300,000 data points.<\/p>\n<p>Our first step is extracting the data from the JSON files and then loading the data into an appropriate table structure in a GridDB database.<\/p>\n<p>The full source code for this article can be found here: <a href=\"https:\/\/github.com\/retowyss\/pc-benchmarking-r-griddb\">Source Code<\/a><\/p>\n<h2>Extracting CapFrameX data from JSON<\/h2>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># The data and entire project is available for download at: \n# https:\/\/github.com\/retowyss\/pc-benchmarking-r-griddb\n\nlibrary(tidyverse)\nlibrary(jsonlite)\n\n# This is just some janitorial data wrangling\n# The function reads the data captured by CapFrameX and makes it available\n# in a easy to use format.\n# Returns a list of three things: system-info, capture-data, sensor-data\nread_capframex_json &lt;- function(x) {\n  capframe_data &lt;- read_json(x, simplifyVector = TRUE)\n  \n  # We need a common length for the captured sensor data because some rows\n  # are length n and some are n-k \n  common_n &lt;- length(capframe_data$Runs$SensorData2$MeasureTime$Values[[1]])\n  \n  list(\n    info    = capframe_data$Info %>% \n      keep(~!is.null(.)) %>% \n      as_tibble(),\n    capture = as_tibble(map(capframe_data$Runs$CaptureData, ~ .[[1]])),\n    sensors = imap_dfc(capframe_data$Runs$SensorData2, function(df, names) {\n      \n      m &lt;- length(df$Values[[1]])\n      vals &lt;- vector(mode = typeof(df$Values[[1]]), common_n)\n      \n      # if vector is shorter, we fill last value\n      if(m &lt; common_n) {\n        vals &lt;- c(df$Values[[1]], rep(df$Values[[1]][m], common_n - m))\n      } else {\n        vals &lt;- (df$Value[[1]])[1:common_n]\n      }\n      \n      res &lt;- list()\n      # Some list names are not appropriate as tibble headers\n      n &lt;- str_remove(str_replace_all(names, \"\/\", \"_\"), \"_\")\n      res[[n]] &lt;- vals\n      \n      as_tibble(res)\n    })\n  )\n}\n\ncapframex_data &lt;- read_capframex_json(\"data\/CapFrameX-DOOMEternalx64vk.exe-2.json\")<\/code><\/pre>\n<\/div>\n<p>For our purposes, we keep as little data as necessary, but there&#8217;s a lot more; feel free to explore.<\/p>\n<p>The capture data creates one data point per frame (<code>MsBetweenPresents<\/code>), which means that the number of rows we end up with when capturing in a fixed time window is variable. However, the sensor data is polled in a relatively fixed interval (<code>BetweenMeasureTime<\/code>) of 250ms, although we can see that there is some variation.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">capframex_data$info %>% \n  select(Processor, GPU, SystemRam, GameName, OS, Motherboard) %>% \n  knitr::kable()<\/code><\/pre>\n<\/div>\n<table>\n<thead>\n<tr>\n<th align=\"left\">Processor<\/th>\n<th align=\"left\">GPU<\/th>\n<th align=\"left\">SystemRam<\/th>\n<th align=\"left\">GameName<\/th>\n<th align=\"left\">OS<\/th>\n<th align=\"left\">Motherboard<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1080 Ti<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">Doom Eternal<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The info table contains the PC system hardware (Processor, GPU, RAM, Motherboard) and software data (Game, Operating System).<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">capframex_data$capture %>% \n  select(TimeInSeconds, MsBetweenPresents) %>% \n  head(n = 3) %>% \n  knitr::kable()<\/code><\/pre>\n<\/div>\n<table>\n<thead>\n<tr>\n<th align=\"right\">TimeInSeconds<\/th>\n<th align=\"right\">MsBetweenPresents<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"right\">0&#46;0000000<\/td>\n<td align=\"right\">8&#46;2026<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">0&#46;0058994<\/td>\n<td align=\"right\">5&#46;8994<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">0&#46;0142062<\/td>\n<td align=\"right\">8&#46;3068<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The capture tables contains performance data. The first frame recorded at time = 0 (<code>TimeInSeconds<\/code>) took 8.2ms (<code>MsBetweenPresents<\/code>) for the hardware to render. The second frame took 5.9ms (<code>MsBetweenPresents<\/code>), so relative to the start of the session 0.0059 (<code>TimeInSeconds<\/code>) seconds had passed.<\/p>\n<p>We call this performance data because better hardware uses less time per frame, which means it produces more frames per second (FPS) and therefore the animations in game look smoother. But perceived smoothness is not only a factor of the number of frames the hardware can render, but also affected by the variation in frame to frame time; less variation is better. So, recurring large excursions in frame times can be an indicator of performance problems even if the average frame times are good (low).<\/p>\n<ul>\n<li><code>TimeInSeconds<\/code>: Time in seconds since the session was started<\/li>\n<li><code>MsBetweenPresents<\/code>: Time it took to render current frame, essentially <code>TimeInSeconds<\/code> (n) &#8211; <code>TimeInSeconds<\/code>(n &#8211; 1)<\/li>\n<\/ul>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">capframex_data$sensors %>% \n  select(MeasureTime, BetweenMeasureTime,\n   cpu_power = amdcpu_0_power_0,\n   cpu_temperature = amdcpu_0_temperature_0,\n   gpu_clock = nvidiagpu_0_clock_0, \n   gpu_power = nvidiagpu_0_power_0, \n   gpu_temperature = nvidiagpu_0_temperature_0\n  ) %>% \n  head(n = 2) %>% \n  knitr::kable()<\/code><\/pre>\n<\/div>\n<table>\n<thead>\n<tr>\n<th align=\"right\">MeasureTime<\/th>\n<th align=\"right\">BetweenMeasureTime<\/th>\n<th align=\"right\">cpu_power<\/th>\n<th align=\"right\">cpu_temperature<\/th>\n<th align=\"right\">gpu_clock<\/th>\n<th align=\"right\">gpu_power<\/th>\n<th align=\"right\">gpu_temperature<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"right\">0&#46;004<\/td>\n<td align=\"right\">0&#46;004<\/td>\n<td align=\"right\">106&#46;7973<\/td>\n<td align=\"right\">61&#46;750<\/td>\n<td align=\"right\">1961&#46;5<\/td>\n<td align=\"right\">234&#46;502<\/td>\n<td align=\"right\">80<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">0&#46;265<\/td>\n<td align=\"right\">0&#46;261<\/td>\n<td align=\"right\">108&#46;1045<\/td>\n<td align=\"right\">61&#46;625<\/td>\n<td align=\"right\">1961&#46;5<\/td>\n<td align=\"right\">211&#46;884<\/td>\n<td align=\"right\">80<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The sensor data&#8217;s <code>MeasureTime<\/code> is like the capture data&#8217;s <code>TimeInSeconds<\/code>; it tells the time since the session start. However, because the sensor data is polled in fixed intervals and not when a new frame is generated, so the data-points don&#8217;t relate one-to-one.<\/p>\n<ul>\n<li><code>MeasureTime<\/code>: Time in seconds since the session was started<\/li>\n<li><code>BetweenMeasureTime<\/code>: exact time since previous measurement (approximately 250ms)<\/li>\n<li><code>cpu_power<\/code>: The CPU (processor) power consumption in Watts<\/li>\n<li><code>cpu_temperature<\/code>: The CPU temperature in degrees <\/li>\n<li><code>gpu_clock<\/code>: The GPU (graphics card) clock speed in MHz<\/li>\n<li><code>gpu_power<\/code>: The GPU power consumption in Watts<\/li>\n<li><code>gpu_temperature<\/code>: The GPU temperature<\/li>\n<\/ul>\n<h2>Loading CapFrameX data into GridDB<\/h2>\n<p>We create three tables (Info, Capture, and Sensor) in our <a href=\"https:\/\/docs.griddb.net\">GridDB<\/a> and the we build an insert function to populate the tables with a json file. In the Process we also need to add ids to properly reference our relational data points.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># We are using a docker based setup that can run this project ootb\n# it's available here: https:\/\/github.com\/retowyss\/rstudio-server-griddb-docker\n\n# You can set this up without docker, the containers use:\n\n# Latest version griddb                 https:\/\/docs.griddb.net\n# Latest version of R and tidyverse     R >= 4.0.0\n# Latest version of JDBC                https:\/\/github.com\/griddb\/jdbc\n\n# For general setup without docker you can follow this post:\n# https:\/\/griddb.net\/en\/blog\/analyzing-nba-play-by-play-data-using-r-and-griddb\/\n\nlibrary(RJDBC)\ndrv &lt;- JDBC(\n  driverClass = \"com.toshiba.mwcloud.gs.sql.Driver\",\n  # Point this to your gridstore jar\n  classPath = \"\/jdbc\/bin\/gridstore-jdbc.jar\"\n)\n\n# IP and port depend on your setup\ngriddb &lt;- dbConnect(\n  drv, \n  \"jdbc:gs:\/\/172.20.0.42:20001\/dockerGridDB\/public\", \n  \"admin\", \n  \"admin\"\n)\n\n# System info table: cfx_info\ndbSendUpdate(griddb, paste(\n  \"CREATE TABLE IF NOT EXISTS cfx_info\", \n  \"(id INTEGER, Processor STRING, GPU STRING, SystemRam STRING,\", \n  \"GameName STRING, OS STRING, Motherboard STRING);\"\n))\n\n# Frame time capture data: cfx_capture\ndbSendUpdate(griddb, paste(\n  \"CREATE TABLE IF NOT EXISTS cfx_capture\", \n  \"(info_id INTEGER, TimeInSeconds FLOAT, MsBetweenPresents FLOAT);\"\n))\n\n# Sensor data: cfx_sensors\ndbSendUpdate(griddb, paste(\n  \"CREATE TABLE IF NOT EXISTS cfx_sensors\", \n  \"(info_id INTEGER, MeasureTime FLOAT, BetweenMeasureTime FLOAT,\", \n  \"cpu_power FLOAT, cpu_temperature FLOAT, gpu_clock FLOAT, gpu_power FLOAT,\", \n  \"gpu_temperature FLOAT);\"\n))\n\ndbInsertTable &lt;- function(conn, name, df, append = TRUE) {\n  for (i in seq_len(nrow(df))) {\n    dbWriteTable(conn, name, df[i, ], append = append)\n  }\n  invisible(TRUE)\n}\n\n# This is not a \"production\" ready approach of doing this, but it's sufficient\n# for this demo :)\n# Inserts dataset (cfx_data) into database (conn) using ID (uid)\ninsert_cfx_data &lt;- function(conn, cfx_data, uid) {\n  \n  dbInsertTable(conn, \"cfx_info\", \n    cfx_data$info %>% \n      transmute(id = uid, Processor, GPU, SystemRam, GameName, OS, Motherboard)\n  )\n  \n  dbInsertTable(conn, \"cfx_capture\", \n    cfx_data$capture %>% \n      transmute(info_id = uid, TimeInSeconds, MsBetweenPresents)\n  )\n  \n  dbInsertTable(conn, \"cfx_sensors\",\n    cfx_data$sensors %>% \n      transmute(\n        info_id = uid, \n        MeasureTime, \n        BetweenMeasureTime,\n        cpu_power = amdcpu_0_power_0,\n        cpu_temperature = amdcpu_0_temperature_0,\n        gpu_clock = nvidiagpu_0_clock_0, \n        gpu_power = nvidiagpu_0_power_0, \n        gpu_temperature = nvidiagpu_0_temperature_0\n      )            \n  )\n  invisible(TRUE)\n}<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># Insert (this takes a while, don't run while knitting the doc)\njson_files &lt;- list.files(\"data\")\nwalk2(json_files, 1:length(json_files), function(x, i) {\n  insert_cfx_data(griddb, read_capframex_json(paste0(\"data\/\", x)), i)\n})<\/code><\/pre>\n<\/div>\n<p>I collected the data using a single system (Ryzen 9 5900X, 16GB RAM, Windows 11), but I tested multiple games and I tested two different graphics cards (GPU); the GTX 1650 and GTX 1080 Ti.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># Check\ndbGetQuery(griddb,\"SELECT * FROM cfx_info;\") %>% \n  knitr::kable()<\/code><\/pre>\n<\/div>\n<table>\n<thead>\n<tr>\n<th align=\"right\">id<\/th>\n<th align=\"left\">Processor<\/th>\n<th align=\"left\">GPU<\/th>\n<th align=\"left\">SystemRam<\/th>\n<th align=\"left\">GameName<\/th>\n<th align=\"left\">OS<\/th>\n<th align=\"left\">Motherboard<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"right\">1<\/td>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1080 Ti<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">Assassin&#8217;s Creed Valhalla<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">2<\/td>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1650<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">Cyberpunk 2077<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">3<\/td>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1650<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">Doom Eternal<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">4<\/td>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1080 Ti<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">Doom Eternal<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<tr>\n<td align=\"right\">5<\/td>\n<td align=\"left\">AMD Ryzen 9 5900X<\/td>\n<td align=\"left\">NVIDIA GeForce GTX 1650<\/td>\n<td align=\"left\">16GB (2x8GB) 3200MT\/s<\/td>\n<td align=\"left\">ROLLERDROME<\/td>\n<td align=\"left\">Microsoft Windows 11 Pro Build 22000<\/td>\n<td align=\"left\">Gigabyte Technology Co. Ltd. B550I AORUS PRO AX<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We only put a few files into the GridDB database, but already have almost 800,000 rows of capture data.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># Check\ndbGetQuery(griddb,\"SELECT COUNT(*) FROM cfx_capture;\")<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">##         \n## 1 778780<\/code><\/pre>\n<\/div>\n<h2>Creating PC Performance Summaries<\/h2>\n<p>We now want performance summaries for specific CPU, GPU, and game combinations. The PC building company could expand on that idea and compare data to a different system using the same hardware components. This way, they could ensure the newly built system performs within expectations before delivering it to the customer.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># We use paste and str_interp to build up our SQL in a readable and easy to\n# understand way\nget_performance_summary &lt;- function(conn, cpu, gpu, game) {\n  system_info &lt;- paste(\n    \"SELECT ID\",\n    \"FROM cfx_info\",\n    \"WHERE Processor = '${cpu}' AND GPU = '${gpu}' AND GameName = '${game}'\"\n  )\n  \n  capture &lt;- paste(\n    \"SELECT AVG(MsBetweenPresents) AS frame_time,\",\n    \"MAX(TimeInSeconds) AS session_time,\",\n    \"COUNT(*) AS frame_count\",\n    \"FROM (\", system_info, \") info\",\n    \"LEFT JOIN (SELECT * FROM cfx_capture) capture\",\n    \"ON info.id = capture.info_id\"\n  )\n\n  sensors &lt;-paste(\n    \"SELECT AVG(cpu_power) AS cpu_power, \",\n    \"AVG(cpu_temperature) AS cpu_temperature,\",\n    \"AVG(gpu_clock) AS gpu_clock, AVG(gpu_power) AS gpu_power,\",\n    \"AVG(gpu_temperature) AS gpu_temperature\",\n    \"FROM (\", system_info, \") info\",\n    \"LEFT JOIN (SELECT * FROM cfx_sensors) sensors\",\n    \"ON info.id = sensors.info_id\"\n  )\n  \n  capture_res &lt;- dbGetQuery(conn, str_interp(capture))\n  sensors_res &lt;- dbGetQuery(conn, str_interp(sensors))\n  \n  as_tibble(bind_cols(\n    tibble(cpu = cpu, gpu = gpu, game = game),\n    capture_res %>% \n      mutate(fps = 1000 \/ frame_time), \n    sensors_res\n  ))\n}\n\ngtx_1650_rollerdrome &lt;- get_performance_summary(griddb, \n  cpu =  \"AMD Ryzen 9 5900X\", \n  gpu =  \"NVIDIA GeForce GTX 1650\", \n  game = \"ROLLERDROME\"\n)\n\nglimpse(gtx_1650_rollerdrome)<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">## Rows: 1\n## Columns: 12\n## $ cpu             &lt;chr> \"AMD Ryzen 9 5900X\"\n## $ gpu             &lt;\/chr>&lt;chr> \"NVIDIA GeForce GTX 1650\"\n## $ game            &lt;\/chr>&lt;chr> \"ROLLERDROME\"\n## $ frame_time      &lt;dbl> 2.660829\n## $ session_time    &lt;\/dbl>&lt;dbl> 400.8515\n## $ frame_count     &lt;\/dbl>&lt;dbl> 150650\n## $ fps             &lt;\/dbl>&lt;dbl> 375.8227\n## $ cpu_power       &lt;\/dbl>&lt;dbl> 95.65372\n## $ cpu_temperature &lt;\/dbl>&lt;dbl> 56.58357\n## $ gpu_clock       &lt;\/dbl>&lt;dbl> 1848.533\n## $ gpu_power       &lt;\/dbl>&lt;dbl> 74.72834\n## $ gpu_temperature &lt;\/dbl>&lt;dbl> 60.41905&lt;\/dbl>&lt;\/chr><\/code><\/pre>\n<\/div>\n<p>We can also turn that into a text paragraph that could be included in a system report.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">summary2text &lt;- function(summary_data) {\n  spinable &lt;-paste0(\n    \"Your system featuring a ${cpu} and ${gpu} performance in \", \n    \"a ${round(session_time\/60)} minutes session of ${game} \",\n    \"was ${round(fps)} FPS.\",\n    \"The graphics card used ${round(gpu_power)}W and \",\n    \"ran at ${round(gpu_temperature)}\u00b0C, \",\n    \"while the CPU used ${round(cpu_power)}W and \", \n    \"ran at ${round(cpu_temperature)}\u00b0C\"\n  )\n  \n  str_interp(spinable, env = summary_data)\n}\n\nsummary2text(gtx_1650_rollerdrome)<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">## [1] \"Your system featuring a AMD Ryzen 9 5900X and NVIDIA GeForce GTX 1650 performance in a 7 minutes session of ROLLERDROME was 376 FPS.The graphics card used 75W and ran at 60\u00b0C, while the CPU used 96W and ran at 57\u00b0C\"<\/code><\/pre>\n<\/div>\n<h2>Temporal Analysis<\/h2>\n<p>We can do a lot of computations, like calculating summaries, directly on the database, but sometimes we have to pull data out of the database so we can analyse it in detail.<\/p>\n<p>When a device uses more power, its temperature should rise. So, what we should find is that gpu_power correlates with gpu_temperature.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">get_sensor_data &lt;- function(conn, cpu, gpu, game) {\n  system_info &lt;- paste(\n    \"SELECT ID\",\n    \"FROM cfx_info\",\n    \"WHERE Processor = '${cpu}' AND GPU = '${gpu}' AND GameName = '${game}'\"\n  )\n\n  sensors &lt;-paste(\n    \"SELECT *\",\n    \"FROM (\", system_info, \") info\",\n    \"LEFT JOIN (SELECT * FROM cfx_sensors) sensors\",\n    \"ON info.id = sensors.info_id\"\n  )\n\n  sensors_res &lt;- dbGetQuery(conn, str_interp(sensors))\n  \n  cbind(tibble(cpu = cpu, gpu = gpu, game = game), as_tibble(sensors_res))\n}\n\ngtx_1080_ti_doom &lt;- get_sensor_data(griddb, \n  cpu =  \"AMD Ryzen 9 5900X\", \n  gpu =  \"NVIDIA GeForce GTX 1080 Ti\", \n  game = \"Doom Eternal\"                                  \n) \n\ngtx_1650_doom &lt;- get_sensor_data(griddb, \n  cpu =  \"AMD Ryzen 9 5900X\", \n  gpu =  \"NVIDIA GeForce GTX 1650\", \n  game = \"Doom Eternal\"                                  \n) \n\ndoom_data &lt;- bind_rows(gtx_1080_ti_doom, gtx_1650_doom)\n\nggplot(doom_data, aes(x = MeasureTime, y = gpu_power, color = gpu)) +\n  geom_line()<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1.png\" alt=\"\" width=\"672\" height=\"480\" class=\"aligncenter size-full wp-image-29493\" srcset=\"\/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1.png 672w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1-300x214.png 300w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1-370x265.png 370w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-11-1-600x429.png 600w\" sizes=\"(max-width: 672px) 100vw, 672px\" \/><\/a><\/p>\n<p>The sudden drops in power are interesting; but they are not erroneous. They correspond to loading checkpoints, falling down cliffs, loading cinematics, etc. The graphics card doesn&#8217;t have to work hard during those brief moments, so it doesn&#8217;t need as much juice.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\">ggplot(doom_data, aes(x = MeasureTime, y = gpu_temperature, color = gpu)) +\n  geom_line()<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1.png\" alt=\"\" width=\"672\" height=\"480\" class=\"aligncenter size-full wp-image-29492\" srcset=\"\/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1.png 672w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1-300x214.png 300w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1-370x265.png 370w, \/wp-content\/uploads\/2023\/02\/unnamed-chunk-12-1-600x429.png 600w\" sizes=\"(max-width: 672px) 100vw, 672px\" \/><\/a><\/p>\n<p>The GTX 1650, which is the less powerful card, shows greater drops in temperature that correspond to checkpoint loading. This is likely because the thermal capacity of the heat sink is lower and it cools down much more quickly than the heft junk of aluminum on the GTX 1080 Ti.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-r\"># Technically there may be a small delay until the gpu-die heats up and\n# the current temperature of the heatsink may also affect the gpu temperature \ncor.test(gtx_1080_ti_doom$gpu_power, gtx_1080_ti_doom$gpu_temperature)<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">## \n##  Pearson's product-moment correlation\n## \n## data:  gtx_1080_ti_doom$gpu_power and gtx_1080_ti_doom$gpu_temperature\n## t = 48.622, df = 7071, p-value &lt; 2.2e-16\n## alternative hypothesis: true correlation is not equal to 0\n## 95 percent confidence interval:\n##  0.4828882 0.5178252\n## sample estimates:\n##       cor \n## 0.5005605<\/code><\/pre>\n<\/div>\n<p>And, we find that correlation.<\/p>\n<h2>Summary<\/h2>\n<ul>\n<li>We&#8217;ve seen how we can extract the JSON saved by CapFrameX using R.<\/li>\n<li>We created a table schema in GridDB and inserted the data from the JSON files.<\/li>\n<li>We used <code>paste<\/code> and <code>str_interp<\/code> to build parameterized queries in R against GridDB.<\/li>\n<li>We used window functions on GridDB so we can avoid loading data onto our workstation.<\/li>\n<li>We pulled data out of GridDB to analyze it in R.<\/li>\n<\/ul>\n<p>If you&#8217;d like to use your own data you may have to adjust some parts of the data extraction process. Here we specifically grab &#8220;amd_cpu&#8221; and &#8220;nvidia_gpu&#8221;, so if you have a different combination you have to rename some selectors, or make it work for any combination; and then share it on Github \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In the company&#8217;s case, this would help ensure performance between systems featuring the same components perform consistently, so they could avoid shipping out malfunctioning systems. In the nerd&#8217;s [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":29394,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46748","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-11T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:56:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/overlay-1024x576.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"576\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"PC Benchmarking with GridDB\",\"datePublished\":\"2023-02-11T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\"},\"wordCount\":1176,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\",\"name\":\"PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png\",\"datePublished\":\"2023-02-11T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:56:28+00:00\",\"description\":\"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png\",\"contentUrl\":\"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png\",\"width\":2560,\"height\":1440},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT","description":"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/","og_locale":"en_US","og_type":"article","og_title":"PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In","og_url":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2023-02-11T08:00:00+00:00","article_modified_time":"2025-11-13T20:56:28+00:00","og_image":[{"width":1024,"height":576,"url":"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/overlay-1024x576.png","type":"image\/png"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"PC Benchmarking with GridDB","datePublished":"2023-02-11T08:00:00+00:00","dateModified":"2025-11-13T20:56:28+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/"},"wordCount":1176,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/","name":"PC Benchmarking with GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png","datePublished":"2023-02-11T08:00:00+00:00","dateModified":"2025-11-13T20:56:28+00:00","description":"Assume someone, either a total nerd or a large custom PC building company, would like to keep track of the performance of the gaming PCs they build. In","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/pc-benchmarking-with-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png","contentUrl":"\/wp-content\/uploads\/2023\/02\/overlay-scaled.png","width":2560,"height":1440},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46748","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/comments?post=46748"}],"version-history":[{"count":1,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46748\/revisions"}],"predecessor-version":[{"id":51417,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/posts\/46748\/revisions\/51417"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media\/29394"}],"wp:attachment":[{"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/media?parent=46748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/categories?post=46748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb.net\/en\/wp-json\/wp\/v2\/tags?post=46748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}