Skip to content

Commit 5d3389b

Browse files
committed
Added sql-bricks, updated results to match the newest versions of all libraries
1 parent 0393648 commit 5d3389b

File tree

4 files changed

+214
-142
lines changed

4 files changed

+214
-142
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
node_modules
2+
package-lock.json

README.md

+42-31
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ xql-bench
33

44
A tool that measures performance of SQL query builders for node.js. It has been written to tune xql.js library, but more modules were included for comparison purposes.
55

6-
* [Official Repository (exceptionaljs/xql-bench)](https://github.com/exceptionaljs/xql-bench)
6+
* [Official Repository (jsstuff/xql-bench)](https://github.com/jsstuff/xql-bench)
77
* [Public Domain (unlicense.org)](http://unlicense.org)
88

99
Libraries
@@ -12,48 +12,59 @@ Libraries
1212
At the moment these libraries are tested:
1313

1414
* knex
15+
* sql-bricks
1516
* squel
1617
* xql
18+
* Don't see your favorite library? Make a pull request!
1719

18-
Where `xql` and `knex` produce well formed output (strings are formatted and escaped), but `squel` doesn't seem to be escaping identifiers and values. The purpose of this tool is benchmark, not to check for a proper escaping, so libraries that don't escape have an advantage.
20+
21+
Where `xql` and `knex` produce well formed output (strings are formatted and escaped), but `squel` doesn't seem to be escaping identifiers and values. The purpose of this tool is to benchmark and not to check for a proper escaping, however, libraries that don't escape by default are dangerous and have an advantage as escaping also costs some cycles.
1922

2023
Results
2124
=======
2225

23-
These results were obtained on a development machine by running `node xql-bench.js` or `npm run bench`. The actual times are not important as these will vary depending on your CPU and node version, however, the comparison of times with other tests matters. The run is currently configured to build 100000 queries per test, but it can be modified by changing `Options.quantity`.
26+
These results were obtained on a development machine by running `node xql-bench.js`. The actual times are not important as these will vary depending on your CPU and node version, however, the comparison of times with other tests matters. The run is currently configured to build 100000 queries per test, but it can be modified by changing `Options.quantity`.
2427

2528
```
26-
xql.js 1.0.0
27-
SELECT_0: 0.153 [s]: SELECT "a", "b", "c" FROM "x";
28-
SELECT_1: 0.262 [s]: SELECT "a", "b", "c" FROM "x" WHERE "enabled" = TRUE OFFSET 100 LIMIT 50;
29-
SELECT_2: 0.412 [s]: SELECT "a", "b", "c" FROM "x" WHERE "enabled" = FALSE AND "pending" = FALSE AND "blocked" = FALSE;
30-
SELECT_3: 0.378 [s]: SELECT "x"."a", "x"."b", "y"."c" FROM "x" INNER JOIN "y" ON "x"."uid" = "y"."uid";
31-
INSERT_0: 0.178 [s]: INSERT INTO "x" ("a", "b", "c") VALUES (0, FALSE, E'\'someText"');
32-
UPDATE_0: 0.270 [s]: UPDATE "x" SET "a" = 1, "b" = 2, "c" = E'\'"?someStringToBeEscaped\'' WHERE "uid" = 1;
33-
DELETE_0: 0.118 [s]: DELETE FROM "x" WHERE "uid" >= 1;
34-
35-
Knex 0.11.1
36-
SELECT_0: 0.464 [s]: select "a", "b", "c" from "x"
37-
SELECT_1: 1.898 [s]: select "a", "b", "c" from "x" where "enabled" = true limit 50 offset 100
38-
SELECT_2: 2.007 [s]: select "a", "b", "c" from "x" where "enabled" = false and "pending" = false and "blocked" = false
39-
SELECT_3: 1.460 [s]: select "x"."a", "x"."b", "y"."c" from "x" inner join "y" on "x"."uid" = "y"."uid"
40-
INSERT_0: 2.020 [s]: insert into "x" ("a", "b", "c") values (0, false, '''someText"')
41-
UPDATE_0: 2.633 [s]: update "x" set "a" = 1, "b" = 2, "c" = '''"?someStringToBeEscaped''' where "uid" = 1
42-
DELETE_0: 0.945 [s]: delete from "x" where "uid" >= 1
43-
44-
Squel 5.0.4
45-
SELECT_0:27.740 [s]: SELECT a, b, c FROM x
46-
SELECT_1:28.423 [s]: SELECT a, b, c FROM x WHERE (enabled = TRUE) LIMIT 50 OFFSET 100
47-
SELECT_2:28.766 [s]: SELECT a, b, c FROM x WHERE (enabled = FALSE) AND (pending = FALSE) AND (blocked = FALSE)
48-
SELECT_3:28.012 [s]: SELECT x.uid, x.name, r.granted FROM x LEFT JOIN y `x.uid = y.uid`
49-
INSERT_0:10.326 [s]: INSERT INTO x (a, b, c) VALUES (0, FALSE, ''someText"')
50-
UPDATE_0:14.354 [s]: UPDATE x SET a = 1, b = 2, c = ''"?someStringToBeEscaped'' WHERE (uid = 1)
51-
DELETE_0:14.767 [s]: DELETE FROM x WHERE (uid >= 1)
29+
Knex 0.15.2
30+
SELECT_0: 1.227 [s]: select `a`, `b`, `c` from `x`
31+
SELECT_1: 1.514 [s]: select `a`, `b`, `c` from `x` where `enabled` = true limit 50 offset 100
32+
SELECT_2: 1.549 [s]: select `a`, `b`, `c` from `x` where `enabled` = false and `pending` = false and `blocked` = false
33+
SELECT_3: 1.701 [s]: select `x`.`a`, `x`.`b`, `y`.`c` from `x` inner join `y` on `x`.`uid` = `y`.`uid`
34+
INSERT_0: 1.343 [s]: insert into `x` (`a`, `b`, `c`) values (0, false, '''someText"')
35+
UPDATE_0: 1.730 [s]: update `x` set `a` = 1, `b` = 2, `c` = '''"?someStringToBeEscaped''' where `uid` = 1
36+
DELETE_0: 1.100 [s]: delete from `x` where `uid` >= 1
37+
38+
SqlBricks 2.0.3
39+
SELECT_0: 1.736 [s]: SELECT a, b, c FROM x
40+
SELECT_1: 2.114 [s]: SELECT a, b, c FROM x WHERE enabled = TRUE
41+
SELECT_2: 2.408 [s]: SELECT a, b, c FROM x WHERE enabled = FALSE AND pending = FALSE AND blocked = FALSE
42+
SELECT_3: 2.079 [s]: SELECT x.a, x.b, x.c FROM x LEFT JOIN y ON x.uid = y.uid
43+
INSERT_0: 1.020 [s]: INSERT INTO x (a, b, c) VALUES (0, FALSE, '''someText"')
44+
UPDATE_0: 1.180 [s]: UPDATE x SET a = 1, b = 2, c = '''"?someStringToBeEscaped''' WHERE uid = 1
45+
DELETE_0: 0.567 [s]: DELETE FROM x WHERE uid = 1
46+
47+
Squel 5.12.2
48+
SELECT_0:20.905 [s]: SELECT a, b, c FROM x
49+
SELECT_1:21.648 [s]: SELECT a, b, c FROM x WHERE (enabled = TRUE) LIMIT 50 OFFSET 100
50+
SELECT_2:19.820 [s]: SELECT a, b, c FROM x WHERE (enabled = FALSE) AND (pending = FALSE) AND (blocked = FALSE)
51+
SELECT_3:19.500 [s]: SELECT x.a, x.b, x.c FROM x LEFT JOIN y `x.uid = y.uid`
52+
INSERT_0: 7.240 [s]: INSERT INTO x (a, b, c) VALUES (0, FALSE, ''someText"')
53+
UPDATE_0:10.494 [s]: UPDATE x SET a = 1, b = 2, c = ''"?someStringToBeEscaped'' WHERE (uid = 1)
54+
DELETE_0:11.295 [s]: DELETE FROM x WHERE (uid >= 1)
55+
56+
xql.js 1.4.3
57+
SELECT_0: 0.090 [s]: SELECT "a", "b", "c" FROM "x";
58+
SELECT_1: 0.193 [s]: SELECT "a", "b", "c" FROM "x" WHERE "enabled" = TRUE LIMIT 50 OFFSET 100;
59+
SELECT_2: 0.257 [s]: SELECT "a", "b", "c" FROM "x" WHERE "enabled" = FALSE AND "pending" = FALSE AND "blocked" = FALSE;
60+
SELECT_3: 0.275 [s]: SELECT "x"."a", "x"."b", "y"."c" FROM "x" INNER JOIN "y" ON "x"."uid" = "y"."uid";
61+
INSERT_0: 0.183 [s]: INSERT INTO "x" ("a", "b", "c") VALUES (0, FALSE, E'\'someText"');
62+
UPDATE_0: 0.255 [s]: UPDATE "x" SET "a" = 1, "b" = 2, "c" = E'\'"?someStringToBeEscaped\'' WHERE "uid" = 1;
63+
DELETE_0: 0.110 [s]: DELETE FROM "x" WHERE "uid" >= 1;
5264
```
5365

5466
Conclusion
5567
----------
5668

57-
The winner is xql.js! It's more than 3 times faster than Knex and 10 to 100 times faster than Squel (maybe some coffee script issue, hard to tell why the difference is so huge, seems unrealistic). So the conclusion would be that full-featured doesn't necessarily have to be slow, and lightweight doesn't necessarily have to be fast. xql.js has been designed keeping performance in mind, it doesn't create unnecessary objects if they are not needed, and it allows to mix JS types with expression nodes to avoid creating nodes that just wrap identifiers or values. It contains also very optimized escaping and query substitution implementation, but it seems that the design of the library plays more important role in terms of performance than few ultra-optimized functions.
69+
The winner is clearly xql.js as it's many times faster than all other competing libraries. It seems that the xml.js is simply well-written from the performance standpoint. It also provides a lot of features and SQL constructs that other libraries don't offer or only offer through raw-query functionality (adding raw content to the query). The benchmarks were written in a way to not favor any library - they are simple by nature, but it's possible to add more complex queries in the future (and more engines).
5870

59-
It's also hard to tell if the difference between xql.js and Knex would impact the performance of the running application where a query execution requires much more than building a string. However, minimizing the object instantiation is a good practice in any runtime environment; and since node.js is a single-threaded environment improving execution of _blocking_ code is probably always a good idea.

package.json

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,38 @@
11
{
22
"name": "xql-bench",
33
"version": "1.0.0",
4-
4+
"license": "Unlicense",
55
"description": "A tool that measures performance of SQL query builders for node.js.",
6-
"keywords": [ "xql", "knex", "squel", "benchmark", "performance", "sql"],
7-
8-
"homepage": "https://github.com/exceptionaljs/xql-bench",
6+
"keywords": [
7+
"xql",
8+
"knex",
9+
"squel",
10+
"benchmark",
11+
"performance",
12+
"sql"
13+
],
14+
"homepage": "https://github.com/jsstuff/xql-bench",
915
"bugs": {
10-
"url": "https://github.com/exceptionaljs/xql-bench/issues"
16+
"url": "https://github.com/jsstuff/xql-bench/issues"
1117
},
12-
13-
"contributors": [{
14-
"name": "Petr Kobalicek",
15-
"email": "[email protected]",
16-
"url": "http://kobalicek.com"
17-
}],
18-
19-
"license": "Unlicense",
20-
18+
"contributors": [
19+
"Petr Kobalicek <[email protected]> (kobalicek.com)"
20+
],
2121
"main": "xql-bench.js",
22-
2322
"dependencies": {
24-
"knex": "*",
23+
"sql-bricks": "*",
2524
"sqlite3": "*",
25+
"knex": "*",
2626
"squel": "*",
2727
"xql": "*"
2828
},
29-
3029
"devDependencies": {
3130
"mocha": "*"
3231
},
33-
34-
"repository" : {
32+
"repository": {
3533
"type": "git",
36-
"url": "https://github.com/exceptionaljs/xql-bench.git"
34+
"url": "https://github.com/jsstuff/xql-bench.git"
3735
},
38-
3936
"scripts": {
4037
"bench": "node xql-bench.js"
4138
}

0 commit comments

Comments
 (0)