You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+42-31
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@ xql-bench
3
3
4
4
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.
* Don't see your favorite library? Make a pull request!
17
19
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.
19
22
20
23
Results
21
24
=======
22
25
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`.
24
27
25
28
```
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`
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;
52
64
```
53
65
54
66
Conclusion
55
67
----------
56
68
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).
58
70
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.
0 commit comments