more benchmark nonsense
This commit is contained in:
parent
f48d63038d
commit
566c59ec95
8 changed files with 2574 additions and 30 deletions
|
@ -1,9 +1,10 @@
|
||||||
import { summary, run, bench } from 'mitata';
|
import { summary, run, bench } from 'mitata';
|
||||||
import { createRouter, insertItem } from '@mapl/router'
|
import { createRouter, insertItem } from '@mapl/router'
|
||||||
import { compileRouter } from './mapl_compiler.mjs'
|
import { compileRouter } from './mapl_compiler.mjs'
|
||||||
import assert from 'assert'
|
|
||||||
import { compilePaths } from "./router_v2.mjs"
|
import { compilePaths } from "./router_v2.mjs"
|
||||||
import { compilePaths as mainCompiler, compilePathsClosure } from "../router_v2.mjs"
|
import { compilePaths as mainCompiler } from "../router_v2.mjs"
|
||||||
|
import { FlaskaRouter as FlaskaRouterBuffer } from "../flaska_buffer.mjs"
|
||||||
|
import { FlaskaRouter as FlaskaRouterFast } from "../flaska_fast.mjs"
|
||||||
import * as consts from './const.js'
|
import * as consts from './const.js'
|
||||||
|
|
||||||
function printCurrentStatus(fn) {
|
function printCurrentStatus(fn) {
|
||||||
|
@ -36,13 +37,21 @@ function printStatusHelperText() {
|
||||||
bench('noop', () => { });
|
bench('noop', () => { });
|
||||||
bench('noop2', () => { });
|
bench('noop2', () => { });
|
||||||
|
|
||||||
let paths = consts.allManyRoutes.map(x => ({ path: x }))
|
let paths = consts.allRoutes.map(x => ({ path: x }))
|
||||||
let tests = paths.map(p => ([p.path.replace(/:[^/]+/g, '_'), p]))
|
let tests = paths.map(p => ([p.path.replace(/:[^/]+/g, '_'), p]))
|
||||||
let testStrings = tests.map(x => x[0])
|
let testStrings = tests.map(x => x[0])
|
||||||
let testStringsMapl = testStrings.map(x => x.slice(1))
|
let testStringsMapl = testStrings.map(x => x.slice(1))
|
||||||
|
let func = [[testStrings, mainCompiler(paths)]]
|
||||||
|
|
||||||
let func = [[testStrings, ...mainCompiler(paths)]]
|
let flaskaRouterBuffer = new FlaskaRouterBuffer()
|
||||||
func.push([testStrings, ...compilePathsClosure(paths)])
|
flaskaRouterBuffer.paths = paths.slice()
|
||||||
|
flaskaRouterBuffer.compile()
|
||||||
|
func.push([testStrings, flaskaRouterBuffer.match])
|
||||||
|
|
||||||
|
let flaskaRouterFast = new FlaskaRouterFast()
|
||||||
|
flaskaRouterFast.paths = paths.slice()
|
||||||
|
flaskaRouterFast.compile()
|
||||||
|
func.push([testStrings, flaskaRouterFast.match])
|
||||||
|
|
||||||
let maplPaths = paths.map(x => x.path.replace(/::[^\/]+/g, '**').replace(/:[^\/]+/g, '*'))
|
let maplPaths = paths.map(x => x.path.replace(/::[^\/]+/g, '**').replace(/:[^\/]+/g, '*'))
|
||||||
const maplRouter = createRouter();
|
const maplRouter = createRouter();
|
||||||
|
@ -51,15 +60,15 @@ for (let route of maplPaths) {
|
||||||
}
|
}
|
||||||
let maplMatcher = compileRouter(maplRouter)
|
let maplMatcher = compileRouter(maplRouter)
|
||||||
|
|
||||||
func.push([testStringsMapl, maplMatcher, maplMatcher])
|
func.push([testStringsMapl, maplMatcher])
|
||||||
|
|
||||||
for (let [tests, _, fun] of func) {
|
for (let [tests, fun] of func) {
|
||||||
console.log(`--- warming up ${fun.name || 'mapl'} ---`)
|
console.log(`--- warming up ${fun.name || 'mapl'} ---`)
|
||||||
for (var i = 0; i < 10000; i++) {
|
for (var i = 0; i < 100000; i++) {
|
||||||
tests.forEach(fun)
|
tests.forEach(fun)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let [tests, _, fun] of func) {
|
for (let [tests, fun] of func) {
|
||||||
console.log(`--- Sanity checking ${fun.name || 'mapl'} ---`)
|
console.log(`--- Sanity checking ${fun.name || 'mapl'} ---`)
|
||||||
for (let a of tests) {
|
for (let a of tests) {
|
||||||
// console.log(a, fun(a))
|
// console.log(a, fun(a))
|
||||||
|
@ -73,9 +82,9 @@ for (let [_, org] of func) {
|
||||||
printStatusHelperText()
|
printStatusHelperText()
|
||||||
|
|
||||||
summary(() => {
|
summary(() => {
|
||||||
func.forEach(function([tests, _, fun]) {
|
func.forEach(function([tests, fun]) {
|
||||||
// console.log(tests, fun, tests.map(fun))
|
// console.log(tests, fun, tests.map(fun))
|
||||||
bench((fun.name || 'bound mapl').slice(6), function() {
|
bench(fun.name || 'mapl', function() {
|
||||||
return tests.map(fun)
|
return tests.map(fun)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
43
flaska.mjs
43
flaska.mjs
|
@ -63,8 +63,6 @@ const statuses = {
|
||||||
304: true
|
304: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const __paramMapName = '__param'
|
|
||||||
const __fullParamMapName = '__fullparam'
|
|
||||||
|
|
||||||
function assertIsHandler(handler, name) {
|
function assertIsHandler(handler, name) {
|
||||||
if (typeof(handler) !== 'function') {
|
if (typeof(handler) !== 'function') {
|
||||||
|
@ -428,7 +426,6 @@ const regCleanNonAschii = /(?![a-zA-Z_])./g
|
||||||
const regCleanRest = /_+/g
|
const regCleanRest = /_+/g
|
||||||
const regStarDoubleParam = /::[^:/]+/g
|
const regStarDoubleParam = /::[^:/]+/g
|
||||||
const regStarSingleParam = /:[^:/]+/g
|
const regStarSingleParam = /:[^:/]+/g
|
||||||
const SlashCode = '/'.charCodeAt(0)
|
|
||||||
const spaces = ' '
|
const spaces = ' '
|
||||||
|
|
||||||
export class FlaskaRouter {
|
export class FlaskaRouter {
|
||||||
|
@ -535,6 +532,7 @@ export class FlaskaRouter {
|
||||||
let staticPaths = new Map()
|
let staticPaths = new Map()
|
||||||
let paramsPaths = []
|
let paramsPaths = []
|
||||||
let collator = new Intl.Collator('en', { sensitivity: 'accent' });
|
let collator = new Intl.Collator('en', { sensitivity: 'accent' });
|
||||||
|
let sealed = Object.seal({})
|
||||||
|
|
||||||
paths.forEach(function(entry) {
|
paths.forEach(function(entry) {
|
||||||
if (entry.path[0] !== '/') throw new RouterError(entry, null, 'Specified route was missing forward slash at start')
|
if (entry.path[0] !== '/') throw new RouterError(entry, null, 'Specified route was missing forward slash at start')
|
||||||
|
@ -543,7 +541,7 @@ export class FlaskaRouter {
|
||||||
if (entry.path.indexOf('/:') < 0 && separateStatic) {
|
if (entry.path.indexOf('/:') < 0 && separateStatic) {
|
||||||
return staticPaths.set(entry.path, {
|
return staticPaths.set(entry.path, {
|
||||||
path: entry,
|
path: entry,
|
||||||
params: {}
|
params: sealed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,13 +595,15 @@ export class FlaskaRouter {
|
||||||
: '')
|
: '')
|
||||||
}
|
}
|
||||||
|
|
||||||
__treeIntoCompiledCodeReturnPath(indentString, paths, branch, params) {
|
__treeIntoCompiledCodeReturnPath(indentString, paths, branch, params, pathParamMapIndex) {
|
||||||
let pathIndex = paths.indexOf(branch.path)
|
let pathIndex = paths.indexOf(branch.path)
|
||||||
if (pathIndex < 0) {
|
if (pathIndex < 0) {
|
||||||
throw new RouterError(branch.path, null, 'InternalError: Specified path was not found in paths')
|
throw new RouterError(branch.path, null, 'InternalError: Specified path was not found in paths')
|
||||||
}
|
}
|
||||||
|
let mapIndex = pathParamMapIndex.size + 1
|
||||||
|
pathParamMapIndex.set(mapIndex, pathIndex)
|
||||||
let output = '\n' + indentString + `return {`
|
let output = '\n' + indentString + `return {`
|
||||||
output += '\n' + indentString + ` path: paths[${pathIndex}],`
|
output += '\n' + indentString + ` path: paths_${mapIndex},`
|
||||||
if (params.length) {
|
if (params.length) {
|
||||||
output += '\n' + indentString + ` params: {`
|
output += '\n' + indentString + ` params: {`
|
||||||
for (let param of params) {
|
for (let param of params) {
|
||||||
|
@ -611,13 +611,13 @@ export class FlaskaRouter {
|
||||||
}
|
}
|
||||||
output += '\n' + indentString + ` },`
|
output += '\n' + indentString + ` },`
|
||||||
} else {
|
} else {
|
||||||
output += '\n' + indentString + ` params: {},`
|
output += '\n' + indentString + ` {},`
|
||||||
}
|
}
|
||||||
output += '\n' + indentString + `}`
|
output += '\n' + indentString + `}`
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
__treeIntoCompiledCodeBranch(paths, branches, indent = 0, params = []) {
|
__treeIntoCompiledCodeBranch(paths, branches, indent = 0, params = [], pathParamMapIndex) {
|
||||||
let output = ''
|
let output = ''
|
||||||
let indentation = spaces.slice(0, (indent - params.length) * 2)
|
let indentation = spaces.slice(0, (indent - params.length) * 2)
|
||||||
let addEndBracket = true
|
let addEndBracket = true
|
||||||
|
@ -637,8 +637,8 @@ export class FlaskaRouter {
|
||||||
output += `if (str.charCodeAt(${this.__getIndex(indent, 0, params)}) === ${branch.char.charCodeAt(0)}) { // ${branch.char}`
|
output += `if (str.charCodeAt(${this.__getIndex(indent, 0, params)}) === ${branch.char.charCodeAt(0)}) { // ${branch.char}`
|
||||||
|
|
||||||
if (branch.path) {
|
if (branch.path) {
|
||||||
output += '\n' + indentation + ` if (str.length === ${this.__getIndex(indent, 1, params)}) {`
|
output += '\n' + indentation + ` if (strLength === ${this.__getIndex(indent, 1, params)}) {`
|
||||||
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params)
|
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params, pathParamMapIndex)
|
||||||
output += '\n' + indentation + ` }`
|
output += '\n' + indentation + ` }`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -650,10 +650,10 @@ export class FlaskaRouter {
|
||||||
params.push([branch.isParams || branch.isFullParams, paramVarName])
|
params.push([branch.isParams || branch.isFullParams, paramVarName])
|
||||||
|
|
||||||
if (branch.isFullParams) {
|
if (branch.isFullParams) {
|
||||||
output += this.__treeIntoCompiledCodeReturnPath(indentation, paths, branch, params)
|
output += this.__treeIntoCompiledCodeReturnPath(indentation, paths, branch, params, pathParamMapIndex)
|
||||||
} else if (branch.path) {
|
} else if (branch.path) {
|
||||||
output += '\n' + indentation + `if (str.length === ${this.__getIndex(indent, 0, params)}) {`
|
output += '\n' + indentation + `if (strLength === ${this.__getIndex(indent, 0, params)}) {`
|
||||||
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params)
|
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params, pathParamMapIndex)
|
||||||
output += '\n' + indentation + `}`
|
output += '\n' + indentation + `}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -664,7 +664,7 @@ export class FlaskaRouter {
|
||||||
} else {
|
} else {
|
||||||
output += '\n' + indentation + ' '
|
output += '\n' + indentation + ' '
|
||||||
}
|
}
|
||||||
output += this.__treeIntoCompiledCodeBranch(paths, branch.children, indent + 1, params.slice())
|
output += this.__treeIntoCompiledCodeBranch(paths, branch.children, indent + 1, params.slice(), pathParamMapIndex)
|
||||||
}
|
}
|
||||||
if (addEndBracket) {
|
if (addEndBracket) {
|
||||||
output += '\n' + indentation + '} '
|
output += '\n' + indentation + '} '
|
||||||
|
@ -674,7 +674,9 @@ export class FlaskaRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
__treeIntoCompiledCodeClosure(paths, tree, staticList) {
|
__treeIntoCompiledCodeClosure(paths, tree, staticList) {
|
||||||
let output = 'return function RBufferStrSliceClosure(str) {'
|
let pathParamMapIndex = new Map()
|
||||||
|
let output = ''
|
||||||
|
let prefix = ''
|
||||||
if (staticList.size > 0) {
|
if (staticList.size > 0) {
|
||||||
output += '\n let checkStatic = staticList.get(str)'
|
output += '\n let checkStatic = staticList.get(str)'
|
||||||
output += '\n if(checkStatic) {'
|
output += '\n if(checkStatic) {'
|
||||||
|
@ -682,11 +684,17 @@ export class FlaskaRouter {
|
||||||
output += '\n }'
|
output += '\n }'
|
||||||
}
|
}
|
||||||
if (tree.length) {
|
if (tree.length) {
|
||||||
output += '\n ' + this.__treeIntoCompiledCodeBranch(paths, tree, 1, [])
|
output += '\n let strLength = str.length'
|
||||||
|
output += '\n ' + this.__treeIntoCompiledCodeBranch(paths, tree, 1, [], pathParamMapIndex)
|
||||||
|
|
||||||
}
|
}
|
||||||
output += '\n return null'
|
output += '\n return null'
|
||||||
output += '\n}'
|
output += '\n}'
|
||||||
//console.log(output)
|
pathParamMapIndex.forEach(function (val, key) {
|
||||||
|
prefix += `let paths_${key} = paths[${val}]\n`
|
||||||
|
})
|
||||||
|
output = prefix + 'return function flaskaFastRouter(str) {\n "use strict";' + output
|
||||||
|
|
||||||
return new Function('paths', 'staticList', output)(paths, staticList)
|
return new Function('paths', 'staticList', output)(paths, staticList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,6 +1231,7 @@ ctx.state.nonce = nonce;
|
||||||
// Waiting 0.1 second for it to close down
|
// Waiting 0.1 second for it to close down
|
||||||
setTimeout(res, 100)
|
setTimeout(res, 100)
|
||||||
})
|
})
|
||||||
|
this.server.closeAllConnections()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1230
flaska_buffer copy.mjs
Normal file
1230
flaska_buffer copy.mjs
Normal file
File diff suppressed because one or more lines are too long
|
@ -674,7 +674,8 @@ export class FlaskaRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
__treeIntoCompiledCodeClosure(paths, tree, staticList) {
|
__treeIntoCompiledCodeClosure(paths, tree, staticList) {
|
||||||
let output = 'return function RBufferStrSliceClosure(str) {'
|
let output = "'use strict'"
|
||||||
|
output += '\nreturn function flaskaBufferStrClos(str) {'
|
||||||
if (staticList.size > 0) {
|
if (staticList.size > 0) {
|
||||||
output += '\n let checkStatic = staticList.get(str)'
|
output += '\n let checkStatic = staticList.get(str)'
|
||||||
output += '\n if(checkStatic) {'
|
output += '\n if(checkStatic) {'
|
||||||
|
|
1240
flaska_old2.mjs
Normal file
1240
flaska_old2.mjs
Normal file
File diff suppressed because one or more lines are too long
22
temp.mjs
Normal file
22
temp.mjs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
function test1() {
|
||||||
|
delete Object.prototype
|
||||||
|
}
|
||||||
|
var test2 = new Function(`
|
||||||
|
delete Object.prototype
|
||||||
|
`)
|
||||||
|
var test3 = new Function(`
|
||||||
|
'use strict'
|
||||||
|
delete Object.prototype
|
||||||
|
`)
|
||||||
|
|
||||||
|
var test4 = new Function(`
|
||||||
|
'use strict'
|
||||||
|
return function() {
|
||||||
|
delete Object.prototype
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
try { test1() } catch (err) { console.log('test1', err.message) }
|
||||||
|
try { test2() } catch (err) { console.log('test2', err.message) }
|
||||||
|
try { test3() } catch (err) { console.log('test3', err.message) }
|
||||||
|
try { test4()() } catch (err) { console.log('test4', err.message) }
|
|
@ -1072,10 +1072,23 @@ t.describe('#closeAsync()', function() {
|
||||||
assert.strictEqual(err, assertError)
|
assert.strictEqual(err, assertError)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.test('it should call closeAllConnections', async function() {
|
||||||
|
const assertError = new Error('Pirate Fight')
|
||||||
|
let flaska = new Flaska()
|
||||||
|
flaska.server = {
|
||||||
|
close: stub(),
|
||||||
|
closeAllConnections: stub(),
|
||||||
|
}
|
||||||
|
flaska.server.closeAllConnections.throws(assertError)
|
||||||
|
let err = await assert.isRejected(flaska.closeAsync())
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
t.test('should otherwise work', async function() {
|
t.test('should otherwise work', async function() {
|
||||||
let flaska = new Flaska()
|
let flaska = new Flaska()
|
||||||
flaska.server = {
|
flaska.server = {
|
||||||
close: stub()
|
close: stub(),
|
||||||
|
closeAllConnections: stub(),
|
||||||
}
|
}
|
||||||
flaska.server.close.returnWith(function(cb) {
|
flaska.server.close.returnWith(function(cb) {
|
||||||
cb(null, { a: 1 })
|
cb(null, { a: 1 })
|
||||||
|
|
20
test_fast.mjs
Normal file
20
test_fast.mjs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Flaska } from './flaska_fast.mjs'
|
||||||
|
|
||||||
|
const port = 51028
|
||||||
|
const flaska = new Flaska({}, )
|
||||||
|
|
||||||
|
flaska.get('/', function(ctx) {
|
||||||
|
ctx.body = { status: true }
|
||||||
|
})
|
||||||
|
|
||||||
|
flaska.get('/:item/asdf/herp/:derp/bla', function(ctx) {
|
||||||
|
ctx.body = { item: ctx.params.item }
|
||||||
|
})
|
||||||
|
|
||||||
|
flaska.get('/error', function(ctx) {
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
flaska.listen(port, function() {
|
||||||
|
console.log('listening on port', port)
|
||||||
|
})
|
Loading…
Reference in a new issue