Skip to content

Commit

Permalink
perf: fast access to method instead of first access to property every…
Browse files Browse the repository at this point in the history
… time
  • Loading branch information
nigrosimone committed Nov 23, 2024
1 parent b575e14 commit 947fc0d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 56 deletions.
16 changes: 8 additions & 8 deletions src/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ limitations under the License.
const uWS = require("uWebSockets.js");
const Router = require("./router.js");
const { removeDuplicateSlashes, defaultSettings, compileTrust, createETagGenerator, fastQueryParse, NullObject } = require("./utils.js");
const querystring = require("fast-querystring");
const { parse } = require("fast-querystring");
const ViewClass = require("./view.js");
const path = require("path");
const os = require("os");
const { join, resolve } = require("path");
const { cpus } = require("os");
const { Worker } = require("worker_threads");

const cpuCount = os.cpus().length;
const cpuCount = cpus().length;

let workers = [];
let taskKey = 0;
const workerTasks = new NullObject();

function createWorker() {
const worker = new Worker(path.join(__dirname, 'worker.js'));
const worker = new Worker(join(__dirname, 'worker.js'));
workers.push(worker);

worker.on('message', (message) => {
Expand Down Expand Up @@ -87,7 +87,7 @@ class Application extends Router {
}
}
this.set('view', ViewClass);
this.set('views', path.resolve('views'));
this.set('views', resolve('views'));
}

createWorkerTask(resolve, reject) {
Expand Down Expand Up @@ -118,7 +118,7 @@ class Application extends Router {
if(value === 'extended') {
this.settings['query parser fn'] = fastQueryParse;
} else if(value === 'simple') {
this.settings['query parser fn'] = querystring.parse;
this.settings['query parser fn'] = parse;
} else if(typeof value === 'function') {
this.settings['query parser fn'] = value;
} else {
Expand All @@ -131,7 +131,7 @@ class Application extends Router {
this.settings['view cache'] = undefined;
}
} else if(key === 'views') {
this.settings[key] = path.resolve(value);
this.settings[key] = resolve(value);
return this;
} else if(key === 'etag') {
if(typeof value === 'function') {
Expand Down
6 changes: 3 additions & 3 deletions src/declarative.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const acorn = require("acorn");
const { tokenizer, Parser } = require("acorn");
const { stringify } = require("./utils.js");
const uWS = require("uWebSockets.js");

const parser = acorn.Parser;
const parser = Parser;

const allowedResMethods = ['set', 'header', 'setHeader', 'status', 'send', 'end', 'append'];
const allowedIdentifiers = ['query', 'params', ...allowedResMethods];
Expand All @@ -29,7 +29,7 @@ module.exports = function compileDeclarative(cb, app) {
code = code.replace(/function *\(/, "function __cb(");
}

const tokens = [...acorn.tokenizer(code, { ecmaVersion: "latest" })];
const tokens = [...tokenizer(code, { ecmaVersion: "latest" })];

if(tokens.some(token => ['throw', 'new', 'await'].includes(token.value))) {
return false;
Expand Down
30 changes: 15 additions & 15 deletions src/middlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

const fs = require('fs');
const path = require('path');
const { statSync } = require('fs');
const { resolve, join, extname } = require('path');
const bytes = require('bytes');
const zlib = require('fast-zlib');
const { Inflate, Gunzip, BrotliDecompress } = require('fast-zlib');
const typeis = require('type-is');
const querystring = require('fast-querystring');
const { parse } = require('fast-querystring');
const { fastQueryParse, NullObject } = require('./utils.js');

function static(root, options) {
Expand Down Expand Up @@ -51,8 +51,8 @@ function static(root, options) {
} else return next();
}
let _path = url;
let fullpath = path.resolve(path.join(options.root, url));
if(options.root && !fullpath.startsWith(path.resolve(options.root))) {
let fullpath = resolve(join(options.root, url));
if(options.root && !fullpath.startsWith(resolve(options.root))) {
if(!options.fallthrough) {
res.status(403);
return next(new Error('Forbidden'));
Expand All @@ -61,14 +61,14 @@ function static(root, options) {

let stat;
try {
stat = fs.statSync(fullpath);
stat = statSync(fullpath);
} catch(err) {
const ext = path.extname(fullpath);
const ext = extname(fullpath);
let i = 0;
if(ext === '' && options.extensions) {
while(i < options.extensions.length) {
try {
stat = fs.statSync(fullpath + '.' + options.extensions[i]);
stat = statSync(fullpath + '.' + options.extensions[i]);
_path = url + '.' + options.extensions[i];
break;
} catch(err) {
Expand Down Expand Up @@ -96,8 +96,8 @@ function static(root, options) {
}
if(options.index) {
try {
stat = fs.statSync(path.join(fullpath, options.index));
_path = path.join(url, options.index);
stat = statSync(join(fullpath, options.index));
_path = join(url, options.index);
} catch(err) {
if(!options.fallthrough) {
res.status(404);
Expand Down Expand Up @@ -126,11 +126,11 @@ function createInflate(contentEncoding) {
case 'identity':
return;
case 'deflate':
return new zlib.Inflate();
return new Inflate();
case 'gzip':
return new zlib.Gunzip();
return new Gunzip();
case 'br':
return new zlib.BrotliDecompress();
return new BrotliDecompress();
default:
return false;
}
Expand Down Expand Up @@ -320,7 +320,7 @@ const urlencoded = createBodyParser('application/x-www-form-urlencoded', functio
if(options.extended) {
req.body = fastQueryParse(buf.toString(), options);
} else {
req.body = querystring.parse(buf.toString());
req.body = parse(buf.toString());
}
} catch(e) {
return next(e);
Expand Down
36 changes: 18 additions & 18 deletions src/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

const cookie = require("cookie");
const mime = require("mime-types");
const { serialize } = require("cookie");
const { lookup, contentType } = require("mime-types");
const vary = require("vary");
const encodeUrl = require("encodeurl");
const {
Expand All @@ -24,18 +24,18 @@ const {
} = require("./utils.js");
const { Writable } = require("stream");
const { isAbsolute } = require("path");
const fs = require("fs");
const Path = require("path");
const statuses = require("statuses");
const { statSync, createReadStream } = require("fs");
const { normalize, sep, resolve, join, basename } = require("path");
const { message } = require("statuses");
const { sign } = require("cookie-signature");
// events is faster at init, tseep is faster at sending events
// since we create a ton of objects and dont send a ton of events, its better to use events here
const { EventEmitter } = require("events");
const http = require("http");
const { OutgoingMessage } = require("http");
const ms = require('ms');
const etag = require("etag");

const outgoingMessage = new http.OutgoingMessage();
const outgoingMessage = new OutgoingMessage();
const symbols = Object.getOwnPropertySymbols(outgoingMessage);
const kOutHeaders = symbols.find(s => s.toString() === 'Symbol(kOutHeaders)');

Expand Down Expand Up @@ -217,7 +217,7 @@ module.exports = class Response extends Writable {
return this;
}
sendStatus(code) {
return this.status(code).send(statuses.message[+code] ?? code.toString());
return this.status(code).send(message[+code] ?? code.toString());
}
end(data) {
if(this.finished) {
Expand Down Expand Up @@ -350,9 +350,9 @@ module.exports = class Response extends Writable {
this.status(403);
return done(new Error('Forbidden'));
}
const parts = Path.normalize(path).split(Path.sep);
const fullpath = options.root ? Path.resolve(Path.join(options.root, path)) : path;
if(options.root && !fullpath.startsWith(Path.resolve(options.root))) {
const parts = normalize(path).split(sep);
const fullpath = options.root ? resolve(join(options.root, path)) : path;
if(options.root && !fullpath.startsWith(resolve(options.root))) {
this.status(403);
return done(new Error('Forbidden'));
}
Expand Down Expand Up @@ -382,7 +382,7 @@ module.exports = class Response extends Writable {
let stat = options._stat;
if(!stat) {
try {
stat = fs.statSync(fullpath);
stat = statSync(fullpath);
} catch(err) {
return done(err);
}
Expand All @@ -394,7 +394,7 @@ module.exports = class Response extends Writable {

// headers
if(!this.headers['content-type']) {
const m = mime.lookup(fullpath);
const m = lookup(fullpath);
if(m) this.type(m);
else this.type('application/octet-stream');
}
Expand Down Expand Up @@ -487,7 +487,7 @@ module.exports = class Response extends Writable {
opts.start = offset;
opts.end = Math.max(offset, offset + len - 1);
}
const file = fs.createReadStream(fullpath, opts);
const file = createReadStream(fullpath, opts);
pipeStreamOverResponse(this, file, len, callback);
}
}
Expand All @@ -513,7 +513,7 @@ module.exports = class Response extends Writable {
opts = filename;
}
if(!name) {
name = Path.basename(path);
name = basename(path);
}
if(!opts.root && !isAbsolute(path)) {
opts.root = process.cwd();
Expand Down Expand Up @@ -616,7 +616,7 @@ module.exports = class Response extends Writable {
options.path = '/';
}

this.append('Set-Cookie', cookie.serialize(name, val, options));
this.append('Set-Cookie', serialize(name, val, options));
return this;
}
clearCookie(name, options) {
Expand Down Expand Up @@ -704,12 +704,12 @@ module.exports = class Response extends Writable {
this.location(url);
this.status(status);
this.headers['content-type'] = 'text/plain; charset=utf-8';
return this.send(`${statuses.message[status] ?? status}. Redirecting to ${url}`);
return this.send(`${message[status] ?? status}. Redirecting to ${url}`);
}

type(type) {
let ct = type.indexOf('/') === -1
? (mime.contentType(type) || 'application/octet-stream')
? (contentType(type) || 'application/octet-stream')
: type;

return this.set('content-type', ct);
Expand Down
20 changes: 10 additions & 10 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

const mime = require("mime-types");
const path = require("path");
const proxyaddr = require("proxy-addr");
const qs = require("qs");
const querystring = require("fast-querystring");
const { lookup } = require("mime-types");
const { join } = require("path");
const { compile } = require("proxy-addr");
const parseQs = require("qs").parse;
const parseFqs = require("fast-querystring").parse;
const etag = require("etag");
const { Stats } = require("fs");

Expand All @@ -32,11 +32,11 @@ function fastQueryParse(query, options) {
if(len <= 128) {
if(!query.includes('[') && !query.includes('%5B') && !query.includes('.') && !query.includes('%2E')) {
// [Object: null prototype] issue
return {...querystring.parse(query)};
return {...parseFqs(query)};
}
}
// [Object: null prototype] issue
return {...qs.parse(query, options)};
return {...parseQs(query, options)};
}

function removeDuplicateSlashes(path) {
Expand Down Expand Up @@ -141,7 +141,7 @@ function acceptParams(str) {
function normalizeType(type) {
return ~type.indexOf('/') ?
acceptParams(type) :
{ value: (mime.lookup(type) || 'application/octet-stream'), params: {} };
{ value: (lookup(type) || 'application/octet-stream'), params: {} };
}

function stringify(value, replacer, spaces, escape) {
Expand Down Expand Up @@ -176,7 +176,7 @@ const defaultSettings = {
'query parser fn': () => fastQueryParse,
'subdomain offset': 2,
'trust proxy': false,
'views': () => path.join(process.cwd(), 'views'),
'views': () => join(process.cwd(), 'views'),
'view cache': () => process.env.NODE_ENV === 'production',
'x-powered-by': true,
'case sensitive routing': true,
Expand All @@ -202,7 +202,7 @@ function compileTrust(val) {
.map(function (v) { return v.trim() })
}

return proxyaddr.compile(val || []);
return compile(val || []);
}

const shownWarnings = new Set();
Expand Down
4 changes: 2 additions & 2 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

const fs = require("fs");
const { readFileSync } = require("fs");
const { parentPort } = require("worker_threads");

parentPort.on('message', (message) => {
if(message.type === 'readFile') {
try {
const data = fs.readFileSync(message.path);
const data = readFileSync(message.path);
const ab = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
parentPort.postMessage({ key: message.key, data: ab }, [ab]);
} catch(err) {
Expand Down

0 comments on commit 947fc0d

Please sign in to comment.