Skip to content

Instantly share code, notes, and snippets.

@fantix
Last active November 28, 2020 22:20
Show Gist options
  • Save fantix/69647ef79a881b170acceba53f6416e4 to your computer and use it in GitHub Desktop.
Save fantix/69647ef79a881b170acceba53f6416e4 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.1.1/normalize.min.css" rel="stylesheet"
type="text/css"/>
<script charset="utf-8" src="https://d3js.org/d3.v3.js"></script>
<style>
html {
background-color: #ffffff;
}
body {
padding: 20px;
}
.axis path, .axis line {
fill: none;
stroke: #999;
shape-rendering: crispEdges;
}
.axis.x2 path, .axis.x2 line {
display: none;
}
.axis text, .legend text {
font: 12px sans-serif;
fill: #333;
}
.axis.x path {
display: none;
}
.axis text {
fill: #555;
}
.axis line, .axis path {
stroke: #888;
}
.focus line {
stroke: #900;
}
.focus text {
fill: #900;
font: 12px sans-serif;
}
table.results {
width: 100%;
border-collapse: collapse;
}
table.results td, table.results th {
border: 1px solid #999;
padding: 5px;
}
table.results tr.benchmark td {
font-weight: bold;
border-bottom: none;
text-align: center;
}
table.results tr.metric td {
border-top: none;
border-bottom: none;
text-align: right;
}
table.results tr.metric:last-child td {
border-bottom: 1px solid #999;
}
</style>
</head>
<body>
<p><em>Sat Nov 28 13:10:02 2020</em></p>
<h1>PostgreSQL Driver Performance Benchmark Report</h1>
Below are the results of testing PostgreSQL client driver implementations.
Each client is constrained to run in a single process.
Test environment: Darwin 20.1.0 (None, x86_64) on i386.
<h2>Overall Results</h2>
<p>The charts below show the geometric average of all benchmark results.</p>
<svg id="mean-bars" style="width: 80vw"></svg>
<svg id="mean-lats" style="width: 80vw"></svg>
<h2>Individual Benchmarks</h2>
<h3>1-pg_type.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">N/A</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">select typname, typnamespace, typowner, typlen, typbyval, typcategory, typispreferred, typisdefined, typdelim, typrelid, typelem, typarray from pg_type where typtypmod = $1 and typisdefined = $2</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: [-1, True]</pre>
<svg id="query-bars-0" style="width: 80vw"></svg>
<svg id="query-lats-0" style="width: 80vw"></svg>
<h3>2-generate_series.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">N/A</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">SELECT i FROM generate_series(1, $1) AS i</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: [1000]</pre>
<svg id="query-bars-1" style="width: 80vw"></svg>
<svg id="query-lats-1" style="width: 80vw"></svg>
<h3>3-large_object.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">CREATE TABLE _bytes(b bytea); INSERT INTO _bytes(b) (SELECT repeat(&#x27;a&#x27;, 1000)::bytea FROM generate_series(1, 100));</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">SELECT * FROM _bytes</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: []</pre>
<svg id="query-bars-2" style="width: 80vw"></svg>
<svg id="query-lats-2" style="width: 80vw"></svg>
<h3>4-arrays.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">CREATE TABLE _test(a int[]); INSERT INTO _test(a) (SELECT (SELECT array_agg(i) FROM generate_series(1, 100) as s(i)) FROM generate_series(1, 100));</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">SELECT * FROM _test</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: []</pre>
<svg id="query-bars-3" style="width: 80vw"></svg>
<svg id="query-lats-3" style="width: 80vw"></svg>
<h3>5-copyfrom.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">CREATE TABLE _test(a int, b int, c int, d text, e float, f int, g text);</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">COPY _test(a, b, c, d, e, f, g) FROM STDIN</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: [{&#x27;row&#x27;: [10, 11, 10, &#x27;TESTTESTTEST&#x27;, 10.333, 12341234, &#x27;123412341234&#x27;], &#x27;count&#x27;: 10000}]</pre>
<svg id="query-bars-4" style="width: 80vw"></svg>
<svg id="query-lats-4" style="width: 80vw"></svg>
<h3>6-batch.json x10</h3>
<h4>Test Setup</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">CREATE TABLE _test(a int, b int, c int, d text, e float, f int, g text);</pre>
<h4>Test Query</h4>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">INSERT INTO _test (a, b, c, d, e, f, g) VALUES ($1, $2, $3, $4, $5, $6, $7);</pre>
<pre style="white-space: pre-wrap;
margin-bottom: 10px;
margin-left: 40px;">Args: [{&#x27;row&#x27;: [10, 11, 10, &#x27;TESTTESTTEST&#x27;, 10.333, 12341234, &#x27;123412341234&#x27;], &#x27;count&#x27;: 1000}]</pre>
<svg id="query-bars-5" style="width: 80vw"></svg>
<svg id="query-lats-5" style="width: 80vw"></svg>
<h2>Detailed Benchmark Data</h2>
<table class="results">
<thead>
<tr>
<th></th>
<th>Geometric mean</th>
<th>1-pg_type.json x10</th>
<th>2-generate_series.json x10</th>
<th>3-large_object.json x10</th>
<th>4-arrays.json x10</th>
<th>5-copyfrom.json x10</th>
<th>6-batch.json x10</th>
</tr>
</thead>
<tbody>
<tr class="benchmark">
<td>python-aiopg</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>265.1</td>
<td>298.99</td>
<td>521.46</td>
<td>1836.58</td>
<td>1062.41</td>
<td>49.1</td>
<td>23.24</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>155608.79</td>
<td>122285.69</td>
<td>521463.08</td>
<td>183658.12</td>
<td>106241.42</td>
<td>491002.88</td>
<td>23239.0</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>18.12ms</td>
<td>9.78ms</td>
<td>8.83ms</td>
<td>4.3ms</td>
<td>7.12ms</td>
<td>35.85ms</td>
<td>373.38ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>37.671ms</td>
<td>33.416ms</td>
<td>19.159ms</td>
<td>5.439ms</td>
<td>9.405ms</td>
<td>203.137ms</td>
<td>429.571ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>69.3ms</td>
<td>65.24ms</td>
<td>36.43ms</td>
<td>11.89ms</td>
<td>20.08ms</td>
<td>428.95ms</td>
<td>455.07ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>3.341ms (8.87%)</td>
<td>2.478ms (7.42%)</td>
<td>2.672ms (13.94%)</td>
<td>0.525ms (9.65%)</td>
<td>0.612ms (6.51%)</td>
<td>57.017ms (28.07%)</td>
<td>11.457ms (2.67%)</td>
</tr>
<tr class="benchmark">
<td>python-aiopg-tuples</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>659.19</td>
<td>2608.35</td>
<td>6422.55</td>
<td>3014.78</td>
<td>1336.44</td>
<td>50.65</td>
<td>24.0</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>386934.71</td>
<td>1066813.8</td>
<td>6422553.95</td>
<td>301478.41</td>
<td>133643.5</td>
<td>506466.13</td>
<td>24003.54</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>8.185ms</td>
<td>2.54ms</td>
<td>0.83ms</td>
<td>2.43ms</td>
<td>5.93ms</td>
<td>34.96ms</td>
<td>283.03ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>15.141ms</td>
<td>3.829ms</td>
<td>1.554ms</td>
<td>3.313ms</td>
<td>7.476ms</td>
<td>196.896ms</td>
<td>415.178ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>44.899ms</td>
<td>18.26ms</td>
<td>8.12ms</td>
<td>13.57ms</td>
<td>15.28ms</td>
<td>559.7ms</td>
<td>476.1ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>1.749ms (11.55%)</td>
<td>0.574ms (15.0%)</td>
<td>0.202ms (12.98%)</td>
<td>0.442ms (13.35%)</td>
<td>0.49ms (6.56%)</td>
<td>50.269ms (25.53%)</td>
<td>22.683ms (5.46%)</td>
</tr>
<tr class="benchmark">
<td>python-asyncpg 0.21</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>1538.49</td>
<td>5790.69</td>
<td>6389.53</td>
<td>10414.82</td>
<td>5159.42</td>
<td>177.06</td>
<td>37.67</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>903053.68</td>
<td>2368393.32</td>
<td>6389527.09</td>
<td>1041482.12</td>
<td>515941.88</td>
<td>1770566.96</td>
<td>37669.85</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>3.482ms</td>
<td>1.1ms</td>
<td>0.87ms</td>
<td>0.57ms</td>
<td>1.26ms</td>
<td>15.17ms</td>
<td>170.98ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>6.486ms</td>
<td>1.724ms</td>
<td>1.562ms</td>
<td>0.957ms</td>
<td>1.935ms</td>
<td>56.421ms</td>
<td>264.722ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>34.725ms</td>
<td>8.71ms</td>
<td>15.93ms</td>
<td>7.25ms</td>
<td>11.37ms</td>
<td>465.86ms</td>
<td>329.03ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>1.446ms (22.28%)</td>
<td>0.29ms (16.8%)</td>
<td>1.17ms (74.88%)</td>
<td>0.156ms (16.25%)</td>
<td>0.287ms (14.83%)</td>
<td>27.721ms (49.13%)</td>
<td>21.743ms (8.21%)</td>
</tr>
<tr class="benchmark">
<td>python-asyncpg master (7c77c333)</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>2322.07</td>
<td>6207.14</td>
<td>6322.2</td>
<td>10373.14</td>
<td>4821.36</td>
<td>180.55</td>
<td>442.4</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>1362999.99</td>
<td>2538721.68</td>
<td>6322195.11</td>
<td>1037313.53</td>
<td>482135.94</td>
<td>1805496.5</td>
<td>442400.83</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>1.986ms</td>
<td>1.16ms</td>
<td>0.95ms</td>
<td>0.53ms</td>
<td>1.08ms</td>
<td>15.25ms</td>
<td>6.37ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>4.3ms</td>
<td>1.608ms</td>
<td>1.579ms</td>
<td>0.962ms</td>
<td>2.071ms</td>
<td>55.328ms</td>
<td>22.585ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>35.922ms</td>
<td>9.17ms</td>
<td>13.72ms</td>
<td>6.92ms</td>
<td>20.96ms</td>
<td>319.69ms</td>
<td>368.3ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>1.235ms (28.71%)</td>
<td>0.233ms (14.47%)</td>
<td>1.145ms (72.53%)</td>
<td>0.158ms (16.42%)</td>
<td>0.394ms (19.04%)</td>
<td>18.706ms (33.81%)</td>
<td>11.394ms (50.45%)</td>
</tr>
<tr class="benchmark">
<td>golang-pgx</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>2264.58</td>
<td>3398.5</td>
<td>9071.54</td>
<td>9321.6</td>
<td>5837.41</td>
<td>211.7</td>
<td>379.77</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>1329250.84</td>
<td>1389986.63</td>
<td>9071536.83</td>
<td>932159.85</td>
<td>583741.24</td>
<td>2116996.15</td>
<td>379768.84</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>1.012ms</td>
<td>0.33ms</td>
<td>0.19ms</td>
<td>0.11ms</td>
<td>0.81ms</td>
<td>23.6ms</td>
<td>8.13ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>4.392ms</td>
<td>2.936ms</td>
<td>1.097ms</td>
<td>1.067ms</td>
<td>1.707ms</td>
<td>46.617ms</td>
<td>26.236ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>40.853ms</td>
<td>15.56ms</td>
<td>7.16ms</td>
<td>40.03ms</td>
<td>8.16ms</td>
<td>557.78ms</td>
<td>229.02ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>2.148ms (48.92%)</td>
<td>1.698ms (57.82%)</td>
<td>0.579ms (52.82%)</td>
<td>0.654ms (61.32%)</td>
<td>0.624ms (36.56%)</td>
<td>27.071ms (58.07%)</td>
<td>9.045ms (34.47%)</td>
</tr>
<tr class="benchmark">
<td>golang-libpq</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>1252.66</td>
<td>2462.46</td>
<td>5592.42</td>
<td>2579.34</td>
<td>8574.6</td>
<td>85.31</td>
<td>148.7</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>735289.1</td>
<td>1007144.45</td>
<td>5592418.58</td>
<td>257933.93</td>
<td>857459.64</td>
<td>853124.7</td>
<td>148704.0</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>1.944ms</td>
<td>0.74ms</td>
<td>0.34ms</td>
<td>0.34ms</td>
<td>0.42ms</td>
<td>28.48ms</td>
<td>52.68ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>7.964ms</td>
<td>4.055ms</td>
<td>1.782ms</td>
<td>3.871ms</td>
<td>1.161ms</td>
<td>117.033ms</td>
<td>67.153ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>52.373ms</td>
<td>12.62ms</td>
<td>50.55ms</td>
<td>36.56ms</td>
<td>19.88ms</td>
<td>340.99ms</td>
<td>130.53ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>2.698ms (33.88%)</td>
<td>1.412ms (34.83%)</td>
<td>1.611ms (90.36%)</td>
<td>2.739ms (70.75%)</td>
<td>0.399ms (34.39%)</td>
<td>23.955ms (20.47%)</td>
<td>6.476ms (9.64%)</td>
</tr>
<tr class="benchmark">
<td>nodejs-ts-postgres</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>1440.77</td>
<td>1974.71</td>
<td>5896.3</td>
<td>6485.18</td>
<td>3398.84</td>
<td>N/A</td>
<td>24.19</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>480383.69</td>
<td>807655.73</td>
<td>5896297.66</td>
<td>648517.78</td>
<td>339884.02</td>
<td>N/A</td>
<td>24371.54</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>0.967ms</td>
<td>3.73ms</td>
<td>0.77ms</td>
<td>1.07ms</td>
<td>2.12ms</td>
<td>N/A</td>
<td>0.13ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>1.74ms</td>
<td>5.062ms</td>
<td>1.695ms</td>
<td>1.541ms</td>
<td>2.941ms</td>
<td>N/A</td>
<td>0.41ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>19.948ms</td>
<td>19.14ms</td>
<td>17.88ms</td>
<td>15.03ms</td>
<td>15.0ms</td>
<td>N/A</td>
<td>40.94ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>0.615ms (35.34%)</td>
<td>0.934ms (18.44%)</td>
<td>0.635ms (37.47%)</td>
<td>0.5ms (32.41%)</td>
<td>0.856ms (29.12%)</td>
<td>N/A</td>
<td>0.347ms (84.58%)</td>
</tr>
<tr class="benchmark">
<td>nodejs-pg-native</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="metric">
<td>Queries/sec</td>
<td>568.68</td>
<td>761.99</td>
<td>3007.24</td>
<td>1547.37</td>
<td>533.85</td>
<td>N/A</td>
<td>31.42</td>
</tr>
<tr class="metric">
<td>Rows/sec</td>
<td>189512.34</td>
<td>311654.17</td>
<td>3007236.37</td>
<td>154736.9</td>
<td>53385.26</td>
<td>N/A</td>
<td>31574.15</td>
</tr>
<tr class="metric">
<td>Min latency</td>
<td>1.748ms</td>
<td>7.53ms</td>
<td>1.45ms</td>
<td>3.51ms</td>
<td>5.33ms</td>
<td>N/A</td>
<td>0.08ms</td>
</tr>
<tr class="metric">
<td>Mean latency</td>
<td>4.411ms</td>
<td>13.116ms</td>
<td>3.324ms</td>
<td>6.458ms</td>
<td>18.717ms</td>
<td>N/A</td>
<td>0.317ms</td>
</tr>
<tr class="metric">
<td>Max latency</td>
<td>61.588ms</td>
<td>37.24ms</td>
<td>15.4ms</td>
<td>147.24ms</td>
<td>154.93ms</td>
<td>N/A</td>
<td>67.73ms</td>
</tr>
<tr class="metric">
<td>Latency variation</td>
<td>2.137ms (48.46%)</td>
<td>2.466ms (18.8%)</td>
<td>1.07ms (32.2%)</td>
<td>3.522ms (54.55%)</td>
<td>8.253ms (44.1%)</td>
<td>N/A</td>
<td>0.581ms (183.5%)</td>
</tr>
</tbody>
</table>
<script>
var DEFAULT_COLORS = [
"#98abc5", "#6b486b", "#ff8c00", "#8a89a6", "#7b6888", "#a05d56", "#d0743c"
];
function _humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) {
return bytes + ' B';
}
var units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(0) + ' ' + units[u];
}
function _drawLegend(chart, width, sizes) {
var legend = chart.selectAll('legend')
.data(sizes)
.enter()
.append("g")
.attr('class', 'legend')
.attr("transform", "translate(" + width + ", 20)");
legend.append('circle')
.style('fill', function (d, i) {
return DEFAULT_COLORS[i]
})
.attr('cx', 0)
.attr('cy', function (d, i) {
return i * 20
})
.attr('r', 5);
legend.append('text')
.attr('x', 7)
.attr('y', function (d, i) {
return i * 20
})
.attr('alignment-baseline', 'central')
.text(function (d) {
return d;
});
}
function drawBars(elSelector, data, options) {
'use strict';
options = options || {};
// geometry
var fullWidth = (options.width || 1000),
fullHeight = (options.height || 370),
margin = {top: 10, right: 100, bottom: 55, left: 100},
width = fullWidth - margin.left - margin.right,
height = fullHeight - margin.top - margin.bottom,
benchmarks = data;
// data reshape
var maxRps = 0;
benchmarks.forEach(function (bench) {
if (bench.data.rps > maxRps) {
maxRps = bench.data.rps
}
});
var names = benchmarks.map(function (d) {
return d.name
});
// charting
var color = d3.scale.ordinal()
.range(DEFAULT_COLORS);
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .2)
.domain(names);
var y = d3.scale.linear()
.range([height, 0])
.domain([0, maxRps]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[0]
});
var xAxis2 = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[1]
});
var xAxis3 = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[2]
});
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var chart = d3.select(elSelector)
.attr('viewBox', '0 0 ' + fullWidth + ' ' + fullHeight)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(options.showBenchmarkType ? xAxis : xAxis2);
chart.append("g")
.attr("class", "x axis x2")
.attr("transform", "translate(0," + (height + 14) + ")")
.call(options.showBenchmarkType ? xAxis2 : xAxis3);
if (options.showBenchmarkType) {
chart.append("g")
.attr("class", "x axis x2")
.attr("transform", "translate(0," + (height + 28) + ")")
.call(xAxis3);
}
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Rows / sec");
chart.selectAll("rect")
.data(benchmarks)
.enter().append("rect")
.style("fill", function (d, i) {
return color(0);
})
.attr("width", x0.rangeBand())
.attr("x", function (d, i) {
return x0(d.name);
})
.attr("y", function (d) {
return y(d.data.rps);
})
.attr("height", function (d) {
return height - y(d.data.rps);
})
.on("mouseover", function (d, i) {
focusRect
.attr('y', y(d.data.rps) - 9);
focusLine
.attr('y1', y(d.data.rps))
.attr('y2', y(d.data.rps));
focusText
.attr('y', y(d.data.rps))
.text(d3.format("0,000")(Math.round(d.data.rps)));
focus.style("display", null);
})
.on("mouseout", function () {
focus.style("display", 'none');
});
var focus = chart.append('g')
.attr('class', 'focus')
.style('display', 'none');
var focusRect = focus.append('rect')
.attr('x', -margin.left)
.attr('width', margin.left - 6)
.attr('y', 0)
.attr('height', 18)
.attr('fill', 'rgba(255, 255, 255, 0.9)');
var focusLine = focus.append('line')
.attr('x1', -6)
.attr('x2', width - 20)
.attr('y1', 0)
.attr('y2', 0)
.style("stroke-dasharray", "2,2");
var focusText = focus.append('text')
.attr('y', 0)
.attr('x', -9)
.attr('text-anchor', 'end')
.attr('alignment-baseline', 'middle');
};
function drawLats(elSelector, data) {
'use strict';
options = options || {};
// geometry
var fullWidth = (options.width || 1000),
fullHeight = (options.height || 370),
margin = {top: 10, right: 65, bottom: 55, left: 65},
width = fullWidth - margin.left - margin.right,
height = fullHeight - margin.top - margin.bottom,
benchmarks = data;
// data reshape
var maxLat = 0;
benchmarks.forEach(function (bench) {
if (bench.data.latency_percentiles[4][1] > maxLat) {
maxLat = bench.data.latency_percentiles[4][1];
}
});
var names = benchmarks.map(function (d) {
return d.name
});
// charting
var color = d3.scale.ordinal()
.range(DEFAULT_COLORS);
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .2)
.domain(names);
var y = d3.scale.linear()
.range([height, 0])
.domain([0, maxLat]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[0]
});
var xAxis2 = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[1]
});
var xAxis3 = d3.svg.axis()
.scale(x0)
.orient("bottom")
.tickFormat(function (d) {
return d.split('-')[2]
});
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var chart = d3.select(elSelector)
.attr('viewBox', '0 0 ' + fullWidth + ' ' + fullHeight)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(options.showBenchmarkType ? xAxis : xAxis2);
chart.append("g")
.attr("class", "x axis x2")
.attr("transform", "translate(0," + (height + 14) + ")")
.call(options.showBenchmarkType ? xAxis2 : xAxis3);
if (options.showBenchmarkType) {
chart.append("g")
.attr("class", "x axis x2")
.attr("transform", "translate(0," + (height + 28) + ")")
.call(xAxis3);
}
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Latency (msec)");
var g = chart.selectAll("rect")
.data(benchmarks)
.enter().append("g")
.attr('class', 'sub');
g.append('line')
.attr('y1', function (d) {
return y(d.data.latency_percentiles[4][1]);
})
.attr('y2', function (d) {
return y(d.data.latency_percentiles[4][1]);
})
.attr('x1', function (d, i) {
return x0(d.name);
})
.attr('x2', function (d, i) {
return x0(d.name) + x0.rangeBand();
})
.style("stroke", function (d, i) {
return color(0);
});
g.append('line')
.attr('y1', function (d) {
return y(d.data.latency_min);
})
.attr('y2', function (d) {
return y(d.data.latency_min);
})
.attr('x1', function (d, i) {
return x0(d.name);
})
.attr('x2', function (d, i) {
return x0(d.name) + x0.rangeBand();
})
.style("stroke", function (d, i) {
return color(0);
});
g.append('line')
.attr('y1', function (d) {
return y(d.data.latency_percentiles[1][1]);
})
.attr('y2', function (d) {
return y(d.data.latency_percentiles[1][1]);
})
.attr('x1', function (d, i) {
return x0(d.name);
})
.attr('x2', function (d, i) {
return x0(d.name) + x0.rangeBand();
})
.style("stroke", function (d, i) {
return color(0);
});
g.append('line')
.attr('y1', function (d) {
return y(d.data.latency_min);
})
.attr('y2', function (d) {
return y(d.data.latency_percentiles[0][1])
})
.attr('x1', function (d, i) {
return x0(d.name) + x0.rangeBand() / 2;
})
.attr('x2', function (d, i) {
return x0(d.name) + x0.rangeBand() / 2;
})
.style("stroke", function (d, i) {
return color(0);
})
.style("stroke-dasharray", "2,2");
g.append('line')
.attr('y1', function (d) {
return y(d.data.latency_percentiles[4][1]);
})
.attr('y2', function (d) {
return y(d.data.latency_percentiles[2][1])
})
.attr('x1', function (d, i) {
return x0(d.name) + x0.rangeBand() / 2;
})
.attr('x2', function (d, i) {
return x0(d.name) + x0.rangeBand() / 2;
})
.style("stroke", function (d, i) {
return color(0);
})
.style("stroke-dasharray", "2,2");
g.append('rect')
.attr('y', function (d) {
return y(d.data.latency_percentiles[2][1]);
})
.attr('x', function (d, i) {
return x0(d.name);
})
.attr("width", x0.rangeBand())
.attr('height', function (d) {
return Math.abs(y(d.data.latency_percentiles[2][1]) - y(d.data.latency_percentiles[0][1]))
})
.style("stroke", function (d, i) {
return color(0);
})
.style("fill", 'rgba(0, 0, 0, 0)');
g.append('rect')
.attr('y', 0)
.attr('height', height)
.attr('x', function (d, i) {
return x0(d.name);
})
.attr('width', function (d) {
return x0.rangeBand();
})
.style('fill', 'rgba(0, 0, 0, 0)')
.on("mouseout", function (d, i) {
d3.select(this).style('fill', 'rgba(0, 0, 0, 0)');
focus.style('display', 'none');
})
.on("mouseover", function (d, i) {
d3.select(this).style('fill', 'rgba(0, 0, 0, 0.04)');
var yMedian = y(d.data.latency_percentiles[1][1]);
focus
.style('display', null);
focusLine
.attr('y1', yMedian)
.attr('y2', yMedian);
focusRect
.attr('y', yMedian - 9);
focusLine
.attr('y1', yMedian)
.attr('y2', yMedian);
focusText
.attr('y', yMedian)
.text(d3.format(".2f")(d.data.latency_percentiles[1][1]));
});
var focus = chart.append('g')
.attr('class', 'focus')
.style('display', 'none');
var focusRect = focus.append('rect')
.attr('x', -margin.left)
.attr('width', margin.left - 6)
.attr('y', 0)
.attr('height', 18)
.attr('fill', 'rgba(255, 255, 255, 0.9)');
var focusLine = focus.append('line')
.attr('x1', -6)
.attr('x2', width - 20)
.attr('y1', 0)
.attr('y2', 0)
.style("stroke-dasharray", "2,2");
var focusText = focus.append('text')
.attr('y', 0)
.attr('x', -9)
.attr('text-anchor', 'end')
.attr('alignment-baseline', 'middle');
};
var data = {
"date": "%Y-%m-%dT%H:%M:%S%z",
"duration": 30,
"platform": {"cpu": "i386", "arch": "x86_64", "system": "Darwin 20.1.0", "distribution": null},
"concurrency_levels": [10],
"querynames": ["1-pg_type.json", "2-generate_series.json", "3-large_object.json", "4-arrays.json", "5-copyfrom.json", "6-batch.json"],
"queries": [{
"query": "select typname, typnamespace, typowner, typlen, typbyval, typcategory, typispreferred, typisdefined, typdelim, typrelid, typelem, typarray from pg_type where typtypmod = $1 and typisdefined = $2",
"args": [-1, true]
}, {
"query": "SELECT i FROM generate_series(1, $1) AS i",
"args": [1000]
}, {
"setup": "CREATE TABLE _bytes(b bytea); INSERT INTO _bytes(b) (SELECT repeat('a', 1000)::bytea FROM generate_series(1, 100));",
"teardown": "DROP TABLE _bytes;",
"query": "SELECT * FROM _bytes",
"args": []
}, {
"setup": "CREATE TABLE _test(a int[]); INSERT INTO _test(a) (SELECT (SELECT array_agg(i) FROM generate_series(1, 100) as s(i)) FROM generate_series(1, 100));",
"teardown": "DROP TABLE _test;",
"query": "SELECT * FROM _test",
"args": []
}, {
"setup": "CREATE TABLE _test(a int, b int, c int, d text, e float, f int, g text);",
"teardown": "DROP TABLE _test;",
"query": "COPY _test(a, b, c, d, e, f, g) FROM STDIN",
"args": [{"row": [10, 11, 10, "TESTTESTTEST", 10.333, 12341234, "123412341234"], "count": 10000}]
}, {
"setup": "CREATE TABLE _test(a int, b int, c int, d text, e float, f int, g text);",
"teardown": "DROP TABLE _test;",
"query": "INSERT INTO _test (a, b, c, d, e, f, g) VALUES ($1, $2, $3, $4, $5, $6, $7);",
"args": [{"row": [10, 11, 10, "TESTTESTTEST", 10.333, 12341234, "123412341234"], "count": 1000}]
}],
"benchmarks": [
{
"name": "python-aiopg",
"variations": [{
"duration": 30.03,
"queries": 8978,
"qps": 298.99,
"rps": 122285.69,
"latency_min": 9.78,
"latency_mean": 33.416,
"latency_max": 65.24,
"latency_std": 2.478,
"latency_cv": 7.42,
"latency_percentiles": [[25, 31.359], [50, 33.233], [75, 34.624], [90, 36.458], [99, 41.024], [99.99, 65.232]]
}, {
"duration": 30.02,
"queries": 15652,
"qps": 521.46,
"rps": 521463.08,
"latency_min": 8.83,
"latency_mean": 19.159,
"latency_max": 36.43,
"latency_std": 2.672,
"latency_cv": 13.94,
"latency_percentiles": [[25, 17.438], [50, 18.495], [75, 19.571], [90, 21.949], [99, 30.855], [99.99, 36.419]]
}, {
"duration": 30.0,
"queries": 55106,
"qps": 1836.58,
"rps": 183658.12,
"latency_min": 4.3,
"latency_mean": 5.439,
"latency_max": 11.89,
"latency_std": 0.525,
"latency_cv": 9.65,
"latency_percentiles": [[25, 5.161], [50, 5.267], [75, 5.515], [90, 6.134], [99, 7.324], [99.99, 11.07]]
}, {
"duration": 30.01,
"queries": 31881,
"qps": 1062.41,
"rps": 106241.42,
"latency_min": 7.12,
"latency_mean": 9.405,
"latency_max": 20.08,
"latency_std": 0.612,
"latency_cv": 6.51,
"latency_percentiles": [[25, 9.042], [50, 9.233], [75, 9.561], [90, 10.146], [99, 11.644], [99.99, 19.316]]
}, {
"duration": 30.04,
"queries": 1475,
"qps": 49.1,
"rps": 491002.88,
"latency_min": 35.85,
"latency_mean": 203.137,
"latency_max": 428.95,
"latency_std": 57.017,
"latency_cv": 28.07,
"latency_percentiles": [[25, 170.395], [50, 201.21], [75, 235.975], [90, 276.98], [99, 344.315], [99.99, 428.957]]
}, {
"duration": 30.12,
"queries": 700,
"qps": 23.24,
"rps": 23239.0,
"latency_min": 373.38,
"latency_mean": 429.571,
"latency_max": 455.07,
"latency_std": 11.457,
"latency_cv": 2.67,
"latency_percentiles": [[25, 425.11], [50, 431.28], [75, 436.65], [90, 442.34], [99, 449.55], [99.99, 455.079]]
}],
"mean": {
"duration": 30.04,
"queries": 7962.73,
"qps": 265.1,
"rps": 155608.79,
"latency_min": 18.12,
"latency_mean": 37.671,
"latency_max": 69.3,
"latency_std": 3.341,
"latency_cv": 8.87,
"latency_percentiles": [[25, 35.032], [50, 37.067], [75, 39.295], [90, 42.747], [99, 50.562], [99.99, 68.034]]
}
}, {
"name": "python-aiopg-tuples",
"variations": [{
"duration": 30.0,
"queries": 78257,
"qps": 2608.35,
"rps": 1066813.8,
"latency_min": 2.54,
"latency_mean": 3.829,
"latency_max": 18.26,
"latency_std": 0.574,
"latency_cv": 15.0,
"latency_percentiles": [[25, 3.559], [50, 3.72], [75, 3.926], [90, 4.266], [99, 5.829], [99.99, 16.243]]
}, {
"duration": 30.0,
"queries": 192683,
"qps": 6422.55,
"rps": 6422553.95,
"latency_min": 0.83,
"latency_mean": 1.554,
"latency_max": 8.12,
"latency_std": 0.202,
"latency_cv": 12.98,
"latency_percentiles": [[25, 1.439], [50, 1.502], [75, 1.595], [90, 1.744], [99, 2.217], [99.99, 7.295]]
}, {
"duration": 30.0,
"queries": 90451,
"qps": 3014.78,
"rps": 301478.41,
"latency_min": 2.43,
"latency_mean": 3.313,
"latency_max": 13.57,
"latency_std": 0.442,
"latency_cv": 13.35,
"latency_percentiles": [[25, 3.094], [50, 3.192], [75, 3.365], [90, 3.72], [99, 5.0], [99.99, 9.879]]
}, {
"duration": 30.01,
"queries": 40102,
"qps": 1336.44,
"rps": 133643.5,
"latency_min": 5.93,
"latency_mean": 7.476,
"latency_max": 15.28,
"latency_std": 0.49,
"latency_cv": 6.56,
"latency_percentiles": [[25, 7.192], [50, 7.346], [75, 7.588], [90, 8.019], [99, 9.285], [99.99, 13.05]]
}, {
"duration": 30.03,
"queries": 1521,
"qps": 50.65,
"rps": 506466.13,
"latency_min": 34.96,
"latency_mean": 196.896,
"latency_max": 559.7,
"latency_std": 50.269,
"latency_cv": 25.53,
"latency_percentiles": [[25, 170.675], [50, 194.81], [75, 218.775], [90, 250.218], [99, 321.046], [99.99, 559.707]]
}, {
"duration": 30.2,
"queries": 725,
"qps": 24.0,
"rps": 24003.54,
"latency_min": 283.03,
"latency_mean": 415.178,
"latency_max": 476.1,
"latency_std": 22.683,
"latency_cv": 5.46,
"latency_percentiles": [[25, 409.972], [50, 416.9], [75, 422.735], [90, 444.7], [99, 472.185], [99.99, 476.109]]
}],
"mean": {
"duration": 30.04,
"queries": 19803.21,
"qps": 659.19,
"rps": 386934.71,
"latency_min": 8.185,
"latency_mean": 15.141,
"latency_max": 44.899,
"latency_std": 1.749,
"latency_cv": 11.55,
"latency_percentiles": [[25, 14.135], [50, 14.831], [75, 15.667], [90, 17.065], [99, 21.206], [99.99, 39.959]]
}
}, {
"name": "python-asyncpg 0.21",
"variations": [{
"duration": 30.0,
"queries": 173727,
"qps": 5790.69,
"rps": 2368393.32,
"latency_min": 1.1,
"latency_mean": 1.724,
"latency_max": 8.71,
"latency_std": 0.29,
"latency_cv": 16.8,
"latency_percentiles": [[25, 1.565], [50, 1.635], [75, 1.777], [90, 1.999], [99, 2.865], [99.99, 7.306]]
}, {
"duration": 30.0,
"queries": 191691,
"qps": 6389.53,
"rps": 6389527.09,
"latency_min": 0.87,
"latency_mean": 1.562,
"latency_max": 15.93,
"latency_std": 1.17,
"latency_cv": 74.88,
"latency_percentiles": [[25, 1.204], [50, 1.298], [75, 1.418], [90, 1.661], [99, 6.926], [99.99, 15.207]]
}, {
"duration": 30.0,
"queries": 312451,
"qps": 10414.82,
"rps": 1041482.12,
"latency_min": 0.57,
"latency_mean": 0.957,
"latency_max": 7.25,
"latency_std": 0.156,
"latency_cv": 16.25,
"latency_percentiles": [[25, 0.897], [50, 0.912], [75, 0.941], [90, 1.069], [99, 1.642], [99.99, 3.833]]
}, {
"duration": 30.0,
"queries": 154788,
"qps": 5159.42,
"rps": 515941.88,
"latency_min": 1.26,
"latency_mean": 1.935,
"latency_max": 11.37,
"latency_std": 0.287,
"latency_cv": 14.83,
"latency_percentiles": [[25, 1.8], [50, 1.85], [75, 1.943], [90, 2.181], [99, 3.072], [99.99, 7.77]]
}, {
"duration": 30.02,
"queries": 5315,
"qps": 177.06,
"rps": 1770566.96,
"latency_min": 15.17,
"latency_mean": 56.421,
"latency_max": 465.86,
"latency_std": 27.721,
"latency_cv": 49.13,
"latency_percentiles": [[25, 46.401], [50, 53.09], [75, 60.732], [90, 68.737], [99, 216.617], [99.99, 465.859]]
}, {
"duration": 30.18,
"queries": 1137,
"qps": 37.67,
"rps": 37669.85,
"latency_min": 170.98,
"latency_mean": 264.722,
"latency_max": 329.03,
"latency_std": 21.743,
"latency_cv": 8.21,
"latency_percentiles": [[25, 263.095], [50, 270.458], [75, 275.908], [90, 280.996], [99, 298.543], [99.99, 329.038]]
}],
"mean": {
"duration": 30.03,
"queries": 46207.09,
"qps": 1538.49,
"rps": 903053.68,
"latency_min": 3.482,
"latency_mean": 6.486,
"latency_max": 34.725,
"latency_std": 1.446,
"latency_cv": 22.28,
"latency_percentiles": [[25, 5.776], [50, 6.098], [75, 6.525], [90, 7.285], [99, 13.652], [99.99, 28.24]]
}
}, {
"name": "python-asyncpg master",
"variations": [{
"duration": 30.0,
"queries": 186221,
"qps": 6207.14,
"rps": 2538721.68,
"latency_min": 1.16,
"latency_mean": 1.608,
"latency_max": 9.17,
"latency_std": 0.233,
"latency_cv": 14.47,
"latency_percentiles": [[25, 1.494], [50, 1.557], [75, 1.641], [90, 1.802], [99, 2.485], [99.99, 7.013]]
}, {
"duration": 30.0,
"queries": 189682,
"qps": 6322.2,
"rps": 6322195.11,
"latency_min": 0.95,
"latency_mean": 1.579,
"latency_max": 13.72,
"latency_std": 1.145,
"latency_cv": 72.53,
"latency_percentiles": [[25, 1.231], [50, 1.322], [75, 1.437], [90, 1.655], [99, 6.796], [99.99, 13.151]]
}, {
"duration": 30.0,
"queries": 311199,
"qps": 10373.14,
"rps": 1037313.53,
"latency_min": 0.53,
"latency_mean": 0.962,
"latency_max": 6.92,
"latency_std": 0.158,
"latency_cv": 16.42,
"latency_percentiles": [[25, 0.9], [50, 0.919], [75, 0.944], [90, 1.077], [99, 1.675], [99.99, 3.429]]
}, {
"duration": 30.0,
"queries": 144646,
"qps": 4821.36,
"rps": 482135.94,
"latency_min": 1.08,
"latency_mean": 2.071,
"latency_max": 20.96,
"latency_std": 0.394,
"latency_cv": 19.04,
"latency_percentiles": [[25, 1.918], [50, 1.957], [75, 2.055], [90, 2.39], [99, 3.47], [99.99, 12.935]]
}, {
"duration": 30.01,
"queries": 5418,
"qps": 180.55,
"rps": 1805496.5,
"latency_min": 15.25,
"latency_mean": 55.328,
"latency_max": 319.69,
"latency_std": 18.706,
"latency_cv": 33.81,
"latency_percentiles": [[25, 46.07], [50, 52.874], [75, 61.21], [90, 71.622], [99, 106.606], [99.99, 319.689]]
}, {
"duration": 30.01,
"queries": 13276,
"qps": 442.4,
"rps": 442400.83,
"latency_min": 6.37,
"latency_mean": 22.585,
"latency_max": 368.3,
"latency_std": 11.394,
"latency_cv": 50.45,
"latency_percentiles": [[25, 20.238], [50, 21.836], [75, 23.709], [90, 25.609], [99, 32.425], [99.99, 365.813]]
}],
"mean": {
"duration": 30.0,
"queries": 69670.82,
"qps": 2322.07,
"rps": 1362999.99,
"latency_min": 1.986,
"latency_mean": 4.3,
"latency_max": 35.922,
"latency_std": 1.235,
"latency_cv": 28.71,
"latency_percentiles": [[25, 3.789], [50, 4.028], [75, 4.335], [90, 4.914], [99, 8.351], [99.99, 27.966]]
}
}, {
"name": "golang-pgx",
"variations": [{
"duration": 30.01,
"queries": 101988,
"qps": 3398.5,
"rps": 1389986.63,
"latency_min": 0.33,
"latency_mean": 2.936,
"latency_max": 15.56,
"latency_std": 1.698,
"latency_cv": 57.82,
"latency_percentiles": [[25, 1.666], [50, 2.846], [75, 3.815], [90, 4.811], [99, 8.342], [99.99, 12.746]]
}, {
"duration": 30.01,
"queries": 272223,
"qps": 9071.54,
"rps": 9071536.83,
"latency_min": 0.19,
"latency_mean": 1.097,
"latency_max": 7.16,
"latency_std": 0.579,
"latency_cv": 52.82,
"latency_percentiles": [[25, 0.62], [50, 1.048], [75, 1.562], [90, 1.778], [99, 2.529], [99.99, 4.493]]
}, {
"duration": 30.01,
"queries": 279695,
"qps": 9321.6,
"rps": 932159.85,
"latency_min": 0.11,
"latency_mean": 1.067,
"latency_max": 40.03,
"latency_std": 0.654,
"latency_cv": 61.32,
"latency_percentiles": [[25, 0.774], [50, 0.949], [75, 1.142], [90, 1.485], [99, 3.13], [99.99, 23.291]]
}, {
"duration": 30.01,
"queries": 175167,
"qps": 5837.41,
"rps": 583741.24,
"latency_min": 0.81,
"latency_mean": 1.707,
"latency_max": 8.16,
"latency_std": 0.624,
"latency_cv": 36.56,
"latency_percentiles": [[25, 1.307], [50, 1.502], [75, 1.858], [90, 2.519], [99, 3.862], [99.99, 5.77]]
}, {
"duration": 30.18,
"queries": 6390,
"qps": 211.7,
"rps": 2116996.15,
"latency_min": 23.6,
"latency_mean": 46.617,
"latency_max": 557.78,
"latency_std": 27.071,
"latency_cv": 58.07,
"latency_percentiles": [[25, 38.261], [50, 41.523], [75, 47.73], [90, 57.026], [99, 115.922], [99.99, 557.777]]
}, {
"duration": 30.11,
"queries": 11436,
"qps": 379.77,
"rps": 379768.84,
"latency_min": 8.13,
"latency_mean": 26.236,
"latency_max": 229.02,
"latency_std": 9.045,
"latency_cv": 34.47,
"latency_percentiles": [[25, 22.467], [50, 25.18], [75, 28.426], [90, 32.316], [99, 47.593], [99.99, 222.917]]
}],
"mean": {
"duration": 30.05,
"queries": 68060.89,
"qps": 2264.58,
"rps": 1329250.84,
"latency_min": 1.012,
"latency_mean": 4.392,
"latency_max": 40.853,
"latency_std": 2.148,
"latency_cv": 48.92,
"latency_percentiles": [[25, 3.106], [50, 4.055], [75, 5.078], [90, 6.239], [99, 10.586], [99.99, 31.392]]
}
}, {
"name": "golang-libpq",
"variations": [{
"duration": 30.01,
"queries": 73895,
"qps": 2462.46,
"rps": 1007144.45,
"latency_min": 0.74,
"latency_mean": 4.055,
"latency_max": 12.62,
"latency_std": 1.412,
"latency_cv": 34.83,
"latency_percentiles": [[25, 2.788], [50, 4.175], [75, 5.005], [90, 5.738], [99, 7.629], [99.99, 11.342]]
}, {
"duration": 30.01,
"queries": 167807,
"qps": 5592.42,
"rps": 5592418.58,
"latency_min": 0.34,
"latency_mean": 1.782,
"latency_max": 50.55,
"latency_std": 1.611,
"latency_cv": 90.36,
"latency_percentiles": [[25, 0.997], [50, 1.749], [75, 1.993], [90, 2.42], [99, 6.42], [99.99, 40.924]]
}, {
"duration": 30.01,
"queries": 77402,
"qps": 2579.34,
"rps": 257933.93,
"latency_min": 0.34,
"latency_mean": 3.871,
"latency_max": 36.56,
"latency_std": 2.739,
"latency_cv": 70.75,
"latency_percentiles": [[25, 2.06], [50, 3.123], [75, 5.006], [90, 7.447], [99, 13.419], [99.99, 25.215]]
}, {
"duration": 30.01,
"queries": 257281,
"qps": 8574.6,
"rps": 857459.64,
"latency_min": 0.42,
"latency_mean": 1.161,
"latency_max": 19.88,
"latency_std": 0.399,
"latency_cv": 34.39,
"latency_percentiles": [[25, 0.915], [50, 1.073], [75, 1.294], [90, 1.574], [99, 2.686], [99.99, 7.955]]
}, {
"duration": 30.18,
"queries": 2575,
"qps": 85.31,
"rps": 853124.7,
"latency_min": 28.48,
"latency_mean": 117.033,
"latency_max": 340.99,
"latency_std": 23.955,
"latency_cv": 20.47,
"latency_percentiles": [[25, 105.145], [50, 112.75], [75, 123.278], [90, 134.66], [99, 255.725], [99.99, 340.995]]
}, {
"duration": 30.11,
"queries": 4478,
"qps": 148.7,
"rps": 148704.0,
"latency_min": 52.68,
"latency_mean": 67.153,
"latency_max": 130.53,
"latency_std": 6.476,
"latency_cv": 9.64,
"latency_percentiles": [[25, 63.525], [50, 66.087], [75, 69.32], [90, 73.147], [99, 94.444], [99.99, 130.531]]
}],
"mean": {
"duration": 30.05,
"queries": 37647.93,
"qps": 1252.66,
"rps": 735289.1,
"latency_min": 1.944,
"latency_mean": 7.964,
"latency_max": 52.373,
"latency_std": 2.698,
"latency_cv": 33.88,
"latency_percentiles": [[25, 5.719], [50, 7.53], [75, 9.058], [90, 10.818], [99, 18.691], [99.99, 40.078]]
}
}, {
"name": "nodejs-ts-postgres",
"variations": [{
"duration": 30.01,
"queries": 59267,
"qps": 1974.71,
"rps": 807655.73,
"latency_min": 3.73,
"latency_mean": 5.062,
"latency_max": 19.14,
"latency_std": 0.934,
"latency_cv": 18.44,
"latency_percentiles": [[25, 4.475], [50, 4.884], [75, 5.278], [90, 5.978], [99, 8.785], [99.99, 17.521]]
}, {
"duration": 30.01,
"queries": 176951,
"qps": 5896.3,
"rps": 5896297.66,
"latency_min": 0.77,
"latency_mean": 1.695,
"latency_max": 17.88,
"latency_std": 0.635,
"latency_cv": 37.47,
"latency_percentiles": [[25, 1.302], [50, 1.537], [75, 1.894], [90, 2.354], [99, 3.958], [99.99, 13.336]]
}, {
"duration": 30.01,
"queries": 194623,
"qps": 6485.18,
"rps": 648517.78,
"latency_min": 1.07,
"latency_mean": 1.541,
"latency_max": 15.03,
"latency_std": 0.5,
"latency_cv": 32.41,
"latency_percentiles": [[25, 1.237], [50, 1.343], [75, 1.716], [90, 2.107], [99, 3.396], [99.99, 9.461]]
}, {
"duration": 30.01,
"queries": 102015,
"qps": 3398.84,
"rps": 339884.02,
"latency_min": 2.12,
"latency_mean": 2.941,
"latency_max": 15.0,
"latency_std": 0.856,
"latency_cv": 29.12,
"latency_percentiles": [[25, 2.352], [50, 2.596], [75, 3.211], [90, 4.108], [99, 6.04], [99.99, 10.198]]
}, {
"duration": 30.01,
"queries": 0,
"qps": 0,
"rps": 0,
"latency_min": 0,
"latency_mean": 0,
"latency_max": 0,
"latency_std": 0,
"latency_cv": 0,
"latency_percentiles": [[25, 0], [50, 0], [75, 0], [90, 0], [99, 0], [99.99, 0]]
}, {
"duration": 30.01,
"queries": 726,
"qps": 24.19,
"rps": 24371.54,
"latency_min": 0.13,
"latency_mean": 0.41,
"latency_max": 40.94,
"latency_std": 0.347,
"latency_cv": 84.58,
"latency_percentiles": [[25, 0.324], [50, 0.381], [75, 0.449], [90, 0.537], [99, 0.904], [99.99, 21.317]]
}],
"mean": {
"duration": 30.01,
"queries": 43240.64,
"qps": 1440.77,
"rps": 480383.69,
"latency_min": 0.967,
"latency_mean": 1.74,
"latency_max": 19.948,
"latency_std": 0.615,
"latency_cv": 35.34,
"latency_percentiles": [[25, 1.406], [50, 1.584], [75, 1.9], [90, 2.307], [99, 3.647], [99.99, 13.688]]
}
}, {
"name": "nodejs-pg-native",
"variations": [{
"duration": 30.02,
"queries": 22877,
"qps": 761.99,
"rps": 311654.17,
"latency_min": 7.53,
"latency_mean": 13.116,
"latency_max": 37.24,
"latency_std": 2.466,
"latency_cv": 18.8,
"latency_percentiles": [[25, 11.349], [50, 12.581], [75, 14.586], [90, 16.602], [99, 20.128], [99.99, 33.214]]
}, {
"duration": 30.01,
"queries": 90257,
"qps": 3007.24,
"rps": 3007236.37,
"latency_min": 1.45,
"latency_mean": 3.324,
"latency_max": 15.4,
"latency_std": 1.07,
"latency_cv": 32.2,
"latency_percentiles": [[25, 2.619], [50, 2.843], [75, 3.485], [90, 5.271], [99, 6.256], [99.99, 8.699]]
}, {
"duration": 30.03,
"queries": 46467,
"qps": 1547.37,
"rps": 154736.9,
"latency_min": 3.51,
"latency_mean": 6.458,
"latency_max": 147.24,
"latency_std": 3.522,
"latency_cv": 54.55,
"latency_percentiles": [[25, 4.99], [50, 5.859], [75, 7.23], [90, 8.688], [99, 13.099], [99.99, 119.267]]
}, {
"duration": 30.03,
"queries": 16029,
"qps": 533.85,
"rps": 53385.26,
"latency_min": 5.33,
"latency_mean": 18.717,
"latency_max": 154.93,
"latency_std": 8.253,
"latency_cv": 44.1,
"latency_percentiles": [[25, 13.866], [50, 17.334], [75, 21.919], [90, 25.216], [99, 45.564], [99.99, 146.778]]
}, {
"duration": 30.01,
"queries": 0,
"qps": 0,
"rps": 0,
"latency_min": 0,
"latency_mean": 0,
"latency_max": 0,
"latency_std": 0,
"latency_cv": 0,
"latency_percentiles": [[25, 0], [50, 0], [75, 0], [90, 0], [99, 0], [99.99, 0]]
}, {
"duration": 30.01,
"queries": 943,
"qps": 31.42,
"rps": 31574.15,
"latency_min": 0.08,
"latency_mean": 0.317,
"latency_max": 67.73,
"latency_std": 0.581,
"latency_cv": 183.5,
"latency_percentiles": [[25, 0.228], [50, 0.28], [75, 0.341], [90, 0.419], [99, 0.769], [99.99, 26.572]]
}],
"mean": {
"duration": 30.02,
"queries": 17072.16,
"qps": 568.68,
"rps": 189512.34,
"latency_min": 1.748,
"latency_mean": 4.411,
"latency_max": 61.588,
"latency_std": 2.137,
"latency_cv": 48.46,
"latency_percentiles": [[25, 3.421], [50, 3.995], [75, 4.873], [90, 6.039], [99, 8.961], [99.99, 42.236]]
}
}
]
};
var options = {
width: 800,
height: 300,
showBenchmarkType: true
}
var meanData = [];
var order = {};
for (var i = 0; i < data.benchmarks.length; i += 1) {
var benchmark = data.benchmarks[i];
meanData.push({
'name': benchmark['name'],
'data': benchmark['mean']
});
}
meanData.sort(function (e1, e2) {
return d3.ascending(e1.data.rps, e2.data.rps);
})
for (var i = 0; i < meanData.length; i += 1) {
order[meanData[i].name] = i;
}
drawBars('#mean-bars', meanData, options);
drawLats('#mean-lats', meanData, options);
var queriesSection = document.getElementById("queries");
var nqueries = data.querynames.length;
for (var i = 0; i < data.concurrency_levels.length; i += 1) {
for (var j = 0; j < data.querynames.length; j += 1) {
var queryData = [];
var offset = i * nqueries + j;
for (var k = 0; k < data.benchmarks.length; k += 1) {
var benchmark = data.benchmarks[k];
queryData.push({
'name': benchmark['name'],
'data': benchmark['variations'][offset]
});
}
queryData.sort(function (e1, e2) {
return d3.ascending(order[e1.name], order[e2.name]);
});
drawBars('#query-bars-' + offset, queryData, options);
drawLats('#query-lats-' + offset, queryData, options);
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment