Created
November 24, 2016 01:33
-
-
Save rtsao/08e6db5409c034b842fe9523181e6410 to your computer and use it in GitHub Desktop.
SSR escaping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const _ = require('lodash'); | |
const randomatic = require('randomatic'); | |
const Benchmark = require('benchmark'); | |
const {table} = require('table'); | |
/** | |
* TEST CODE | |
*/ | |
function control(_string) { | |
const string = _string + ''; | |
const length = string.length; | |
let characters = ''; | |
for (let i = 0; i < length; i++) { | |
switch (string.charCodeAt(i)) { | |
case 38: | |
characters += '&'; | |
break; | |
case 39: | |
characters += '''; | |
break; | |
case 34: | |
characters += '"'; | |
break; | |
case 60: | |
characters += '<'; | |
break; | |
case 62: | |
characters += '>'; | |
break; | |
default: | |
characters += string[i]; | |
} | |
} | |
return characters; | |
} | |
var UNSAFE_CHARS_PATTERN = /[<>&"']/g; | |
// Mapping of unsafe HTML and invalid JavaScript line terminator chars to | |
// their Unicode counterparts which are safe to use in JavaScript strings. | |
var HTML_CHARS = { | |
'<' : '<', | |
'>' : '>', | |
'"' : '"', | |
"'" : ''', | |
'&' : '&' | |
}; | |
function getChar(unsafeChar) { | |
return HTML_CHARS[unsafeChar]; | |
} | |
function treatment(_str) { | |
const str = _str + ''; | |
return str.replace(UNSAFE_CHARS_PATTERN, getChar); | |
} | |
/** | |
* BENCHMARK CODE | |
*/ | |
const escapedChars = Object.keys(HTML_CHARS); | |
function generateString(length, escapeProportion) { | |
const str = randomatic('Aa0', length); | |
const numEscaped = Math.ceil(length * escapeProportion); | |
const charArray = str.split(''); | |
const indices = _.range(length); | |
const indicesToReplace = _.sampleSize(indices, numEscaped); | |
indicesToReplace.forEach(index => { | |
charArray[index] = _.sample(escapedChars); | |
}); | |
return charArray.join(''); | |
} | |
const PROPORTIONS = [0, 0.15, 0.30]; | |
const LENGTHS = [8, 16, 32, 64, 128, 256, 512, 1024]; | |
let suites = []; | |
let results = [[' ', ...LENGTHS]]; | |
PROPORTIONS.forEach((proportion, i) => { | |
results[i + 1] = [proportion]; | |
LENGTHS.forEach((length, j) => { | |
const str = generateString(length, proportion); | |
const suite = new Benchmark.Suite; | |
suite | |
.add(`control(${length}, ${proportion})`, function() { | |
control(str); | |
}) | |
.add(`treatment(${length}, ${proportion})`, function() { | |
treatment(str); | |
}) | |
.on('cycle', function(event) { | |
console.log(String(event.target)); | |
}) | |
.on('complete', function() { | |
const fastest = this.filter('fastest').map('name'); | |
results[i + 1][j + 1] = fastest[0].split('(')[0]; | |
console.log('Fastest is ' + fastest + "\n"); | |
}); | |
suites.push(suite); | |
}); | |
}); | |
for (let k = 0; k < suites.length; k++) { | |
suites[k].run({ 'async': false }); | |
} | |
console.log(table(results)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment