Do not handle extremely rare escaped states in <script>; simplify graph to show single average
This commit is contained in:
parent
52592997fb
commit
20c59769fe
|
@ -369,4 +369,4 @@ Special handling of some attributes require case sensitive names and values. For
|
|||
|
||||
`script` and `style` tags must be closed with `</script>` and `</style>` respectively (case sensitive).
|
||||
|
||||
[hyperbuild can handle escaped and double-escaped script content.](./notes/Script%20data.md)
|
||||
hyperbuild does not handle [escaped and double-escaped](./notes/Script%20data.md) script content.
|
||||
|
|
|
@ -5,41 +5,44 @@ const tests = require('./tests');
|
|||
|
||||
const colours = {
|
||||
'hyperbuild': '#041f60',
|
||||
'hyperbuild-nodejs': '#0476d0',
|
||||
'minimize': '#3cacae',
|
||||
'html-minifier': '#5d6c89',
|
||||
'hyperbuild-nodejs': '#1f77b4',
|
||||
'minimize': '#ff7f0e',
|
||||
'html-minifier': '#2ca02c',
|
||||
};
|
||||
|
||||
const programNames = ['minimize', 'html-minifier', 'hyperbuild-nodejs'];
|
||||
|
||||
const chartOptions = (title, displayLegend, yTick = t => t) => ({
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
fontColor: '#333',
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
barPercentage: 0.75,
|
||||
barPercentage: 0.5,
|
||||
gridLines: {
|
||||
color: '#ccc',
|
||||
color: '#e2e2e2',
|
||||
},
|
||||
ticks: {
|
||||
fontColor: '#222',
|
||||
fontColor: '#666',
|
||||
},
|
||||
}],
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
color: '#666',
|
||||
color: '#ccc',
|
||||
},
|
||||
ticks: {
|
||||
callback: yTick,
|
||||
fontColor: '#222',
|
||||
fontColor: '#666',
|
||||
},
|
||||
}],
|
||||
},
|
||||
legend: {
|
||||
display: displayLegend,
|
||||
labels: {
|
||||
fontFamily: 'Ubuntu, sans-serif',
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
fontColor: '#000',
|
||||
},
|
||||
},
|
||||
|
@ -56,31 +59,50 @@ const renderChart = async (file, cfg) => {
|
|||
const testNames = tests.map(t => t.name).sort();
|
||||
|
||||
const speedResults = JSON.parse(fs.readFileSync(path.join(__dirname, 'speed.json'), 'utf8'));
|
||||
const speedData = programNames.map(program => [
|
||||
program,
|
||||
testNames
|
||||
// Get OP/s for each test.
|
||||
.map(test => speedResults[test][program] / speedResults[test]['hyperbuild-nodejs'])
|
||||
// Sum all test OP/s.
|
||||
.reduce((sum, c) => sum + c)
|
||||
// Divide by tests count to get average OP/s.
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => a[1] - b[1]);
|
||||
await renderChart('speed', {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: testNames,
|
||||
datasets: ['hyperbuild', 'hyperbuild-nodejs', 'minimize', 'html-minifier'].map(program => ({
|
||||
label: program,
|
||||
backgroundColor: colours[program],
|
||||
data: testNames.map(test => speedResults[test][program] / speedResults[test]['hyperbuild'] * 100),
|
||||
})),
|
||||
labels: speedData.map(([n]) => n),
|
||||
// Node.js version is close enough to Rust version, so leave out Rust results.
|
||||
// Include it this if this situation changes.
|
||||
datasets: [{
|
||||
label: 'Average relative OP/s',
|
||||
backgroundColor: '#0366d6',
|
||||
data: speedData.map(([_, v]) => v),
|
||||
}],
|
||||
},
|
||||
...chartOptions('Relative operations per second (higher is better)', true, tick => `${tick}%`),
|
||||
...chartOptions('Average operations per second (higher is better)', false, tick => `${tick * 100}%`),
|
||||
});
|
||||
|
||||
const sizes = JSON.parse(fs.readFileSync(path.join(__dirname, 'minification.json'), 'utf8'));
|
||||
const sizeData = programNames.map(program => [
|
||||
program,
|
||||
testNames
|
||||
.map(test => sizes[test][program].relative)
|
||||
.reduce((sum, c) => sum + c)
|
||||
/ testNames.length,
|
||||
]).sort((a, b) => b[1] - a[1]);
|
||||
await renderChart('minification', {
|
||||
type: 'bar',
|
||||
scaleFontColor: 'red',
|
||||
data: {
|
||||
labels: testNames,
|
||||
datasets: ['hyperbuild-nodejs', 'html-minifier', 'minimize'].map(program => ({
|
||||
label: program,
|
||||
backgroundColor: colours[program],
|
||||
data: testNames.map(test => sizes[test][program].relative * 100),
|
||||
})),
|
||||
labels: sizeData.map(([n]) => n),
|
||||
datasets: [{
|
||||
label: 'Average minified size',
|
||||
backgroundColor: '#0366d6',
|
||||
data: sizeData.map(([_, v]) => v),
|
||||
}],
|
||||
},
|
||||
...chartOptions('Relative minified HTML file size (lower is better)', true, tick => `${tick}%`),
|
||||
...chartOptions('Average minified size (lower is better)', false, tick => `${tick * 100}%`),
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 493123,
|
||||
"relative": 0.8609366679760814
|
||||
"absolute": 493190,
|
||||
"relative": 0.8610536423552005
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 488822,
|
||||
|
@ -23,8 +23,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 297108,
|
||||
"relative": 0.7413114696833979
|
||||
"absolute": 297113,
|
||||
"relative": 0.7413239451379411
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 298773,
|
||||
|
@ -41,8 +41,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 137131,
|
||||
"relative": 0.8809592640417317
|
||||
"absolute": 137191,
|
||||
"relative": 0.8813447170453742
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 137026,
|
||||
|
@ -59,8 +59,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 271470,
|
||||
"relative": 0.7348248000324821
|
||||
"absolute": 272622,
|
||||
"relative": 0.7379430752365098
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 270604,
|
||||
|
@ -77,8 +77,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 79853,
|
||||
"relative": 0.6335729474118506
|
||||
"absolute": 80085,
|
||||
"relative": 0.6354136913262878
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 79394,
|
||||
|
@ -113,8 +113,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 28860,
|
||||
"relative": 0.5157900380676639
|
||||
"absolute": 28918,
|
||||
"relative": 0.5168266223437528
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 28448,
|
||||
|
@ -131,8 +131,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 1888405,
|
||||
"relative": 0.9523229578616866
|
||||
"absolute": 1888685,
|
||||
"relative": 0.9524641619085946
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 1887947,
|
||||
|
@ -149,8 +149,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 1116125,
|
||||
"relative": 0.7234200454355427
|
||||
"absolute": 1116262,
|
||||
"relative": 0.7235088424307043
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 1115617,
|
||||
|
@ -167,8 +167,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 89741,
|
||||
"relative": 0.5793517065959108
|
||||
"absolute": 89844,
|
||||
"relative": 0.5800166560145643
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 89321,
|
||||
|
@ -185,8 +185,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 273277,
|
||||
"relative": 0.9084916041395864
|
||||
"absolute": 281124,
|
||||
"relative": 0.9345784450288063
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 273174,
|
||||
|
@ -203,8 +203,8 @@
|
|||
"relative": 1
|
||||
},
|
||||
"hyperbuild-nodejs": {
|
||||
"absolute": 1351483,
|
||||
"relative": 0.5539028200832156
|
||||
"absolute": 1354680,
|
||||
"relative": 0.5552131046489897
|
||||
},
|
||||
"html-minifier": {
|
||||
"absolute": 1307563,
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 15 KiB |
|
@ -1,74 +1,74 @@
|
|||
{
|
||||
"Amazon.html": {
|
||||
"hyperbuild": 348.52605821546064,
|
||||
"hyperbuild-nodejs": 165.07093690973286,
|
||||
"html-minifier": 16.107592839431693,
|
||||
"minimize": 99.24208700487603
|
||||
"hyperbuild": 440.8132965717429,
|
||||
"hyperbuild-nodejs": 421.69855021276993,
|
||||
"html-minifier": 17.258795822465824,
|
||||
"minimize": 90.55958994772226
|
||||
},
|
||||
"BBC.html": {
|
||||
"hyperbuild": 498.2348139009136,
|
||||
"hyperbuild-nodejs": 244.6322429720145,
|
||||
"html-minifier": 18.585717845341243,
|
||||
"minimize": 116.27828832819753
|
||||
"hyperbuild": 492.0329453689757,
|
||||
"hyperbuild-nodejs": 471.8584948307175,
|
||||
"html-minifier": 19.7020352249727,
|
||||
"minimize": 104.87178415350614
|
||||
},
|
||||
"Bootstrap.html": {
|
||||
"hyperbuild": 238.21894278610927,
|
||||
"hyperbuild-nodejs": 156.53315203999523,
|
||||
"html-minifier": 8.3990089555115,
|
||||
"minimize": 22.909077061595145
|
||||
"hyperbuild": 231.09665327117622,
|
||||
"hyperbuild-nodejs": 226.67498352524473,
|
||||
"html-minifier": 8.226880597761307,
|
||||
"minimize": 20.13372742812355
|
||||
},
|
||||
"Bing.html": {
|
||||
"hyperbuild": 1737.6334081200116,
|
||||
"hyperbuild-nodejs": 688.4893822559816,
|
||||
"html-minifier": 78.95988809648134,
|
||||
"minimize": 437.5366586028663
|
||||
"hyperbuild": 1778.4702078625266,
|
||||
"hyperbuild-nodejs": 1658.794145375611,
|
||||
"html-minifier": 83.98091409603377,
|
||||
"minimize": 384.94817410652996
|
||||
},
|
||||
"Coding Horror.html": {
|
||||
"hyperbuild": 1197.4089706956722,
|
||||
"hyperbuild-nodejs": 669.904737573913,
|
||||
"html-minifier": 45.643674781314395,
|
||||
"minimize": 173.0258048899911
|
||||
"hyperbuild": 1168.2795366543119,
|
||||
"hyperbuild-nodejs": 1078.459574380092,
|
||||
"html-minifier": 46.48112183626401,
|
||||
"minimize": 153.319841453279
|
||||
},
|
||||
"Google.html": {
|
||||
"hyperbuild": 1123.9206824500823,
|
||||
"hyperbuild-nodejs": 920.376725868044,
|
||||
"html-minifier": 31.321054829311436,
|
||||
"minimize": 369.0906454521445
|
||||
"hyperbuild": 1114.801076060868,
|
||||
"hyperbuild-nodejs": 1019.3514619651979,
|
||||
"html-minifier": 30.027167989715412,
|
||||
"minimize": 332.2243603934142
|
||||
},
|
||||
"Hacker News.html": {
|
||||
"hyperbuild": 1839.8486560618867,
|
||||
"hyperbuild-nodejs": 1255.30693251337,
|
||||
"html-minifier": 67.45295727773244,
|
||||
"minimize": 265.7472608824104
|
||||
"hyperbuild": 1792.733771310799,
|
||||
"hyperbuild-nodejs": 1733.4960660597985,
|
||||
"html-minifier": 66.72358457316844,
|
||||
"minimize": 227.14057132045096
|
||||
},
|
||||
"NY Times.html": {
|
||||
"hyperbuild": 206.64831284965635,
|
||||
"hyperbuild-nodejs": 54.49167941039783,
|
||||
"html-minifier": 7.336661842305721,
|
||||
"minimize": 61.264331562390105
|
||||
"hyperbuild": 205.6615989494327,
|
||||
"hyperbuild-nodejs": 184.89340003459205,
|
||||
"html-minifier": 8.051220803993862,
|
||||
"minimize": 57.913234028121984
|
||||
},
|
||||
"Reddit.html": {
|
||||
"hyperbuild": 189.6454899629115,
|
||||
"hyperbuild-nodejs": 84.58158579201455,
|
||||
"html-minifier": 6.305846537661691,
|
||||
"minimize": 45.602895635511416
|
||||
"hyperbuild": 186.794516149638,
|
||||
"hyperbuild-nodejs": 174.40078706592806,
|
||||
"html-minifier": 6.803778440125968,
|
||||
"minimize": 38.92901486989761
|
||||
},
|
||||
"Stack Overflow.html": {
|
||||
"hyperbuild": 795.551445372161,
|
||||
"hyperbuild-nodejs": 496.1578048486152,
|
||||
"html-minifier": 39.331066953478285,
|
||||
"minimize": 154.24858433261213
|
||||
"hyperbuild": 785.6645799343813,
|
||||
"hyperbuild-nodejs": 744.9855971158657,
|
||||
"html-minifier": 40.301363056633434,
|
||||
"minimize": 136.9552445217857
|
||||
},
|
||||
"Twitter.html": {
|
||||
"hyperbuild": 386.0676346339393,
|
||||
"hyperbuild-nodejs": 207.95620261405426,
|
||||
"html-minifier": 42.24757139208541,
|
||||
"minimize": 129.4921832398901
|
||||
"hyperbuild": 368.20636689648717,
|
||||
"hyperbuild-nodejs": 347.59122908382204,
|
||||
"html-minifier": 42.309450954465014,
|
||||
"minimize": 135.2904116989639
|
||||
},
|
||||
"Wikipedia.html": {
|
||||
"hyperbuild": 52.81648307515652,
|
||||
"hyperbuild-nodejs": 32.050455493661815,
|
||||
"html-minifier": 2.394314136599145,
|
||||
"minimize": 8.106531334304298
|
||||
"hyperbuild": 51.59259861536417,
|
||||
"hyperbuild-nodejs": 51.17247467198595,
|
||||
"html-minifier": 2.3748941300695545,
|
||||
"minimize": 7.740053597200842
|
||||
}
|
||||
}
|
BIN
bench/speed.png
BIN
bench/speed.png
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 16 KiB |
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"COMMENT_END": "-->",
|
||||
"STYLE_END": "</style",
|
||||
"SCRIPT_END": "</script",
|
||||
"INSTRUCTION_END": "?>"
|
||||
}
|
||||
|
|
|
@ -1,66 +1,10 @@
|
|||
use crate::err::ProcessingResult;
|
||||
use crate::proc::Processor;
|
||||
|
||||
// See https://www.w3.org/TR/html52/syntax.html#script-data-state and "notes/Script data.md".
|
||||
|
||||
enum State {
|
||||
End,
|
||||
Normal,
|
||||
Escaped,
|
||||
DoubleEscaped,
|
||||
}
|
||||
|
||||
// TODO Optimise all functions in this file.
|
||||
|
||||
fn process_script_data_double_escaped(proc: &mut Processor) -> ProcessingResult<State> {
|
||||
loop {
|
||||
if chain!(proc.match_seq(b"</script").keep().matched()) {
|
||||
return Ok(State::Escaped);
|
||||
};
|
||||
if chain!(proc.match_seq(b"-->").keep().matched()) {
|
||||
return Ok(State::Normal);
|
||||
};
|
||||
proc.accept()?;
|
||||
};
|
||||
}
|
||||
|
||||
fn process_script_data_escaped(proc: &mut Processor) -> ProcessingResult<State> {
|
||||
loop {
|
||||
if chain!(proc.match_seq(b"<script").keep().matched()) {
|
||||
return Ok(State::DoubleEscaped);
|
||||
};
|
||||
if chain!(proc.match_seq(b"</script").matched()) {
|
||||
return Ok(State::End);
|
||||
};
|
||||
if chain!(proc.match_seq(b"-->").keep().matched()) {
|
||||
return Ok(State::Normal);
|
||||
};
|
||||
proc.accept()?;
|
||||
};
|
||||
}
|
||||
|
||||
fn process_script_data(proc: &mut Processor) -> ProcessingResult<State> {
|
||||
loop {
|
||||
if chain!(proc.match_seq(b"</script").matched()) {
|
||||
return Ok(State::End);
|
||||
};
|
||||
if chain!(proc.match_seq(b"<!--").keep().matched()) {
|
||||
return Ok(State::Escaped);
|
||||
};
|
||||
proc.accept()?;
|
||||
};
|
||||
}
|
||||
include!(concat!(env!("OUT_DIR"), "/gen_pattern_SCRIPT_END.rs"));
|
||||
|
||||
pub fn process_script(proc: &mut Processor) -> ProcessingResult<()> {
|
||||
// NOTE: See "notes/Script data.md".
|
||||
let mut state = State::Normal;
|
||||
loop {
|
||||
state = match state {
|
||||
State::End => break,
|
||||
State::Normal => process_script_data(proc)?,
|
||||
State::Escaped => process_script_data_escaped(proc)?,
|
||||
State::DoubleEscaped => process_script_data_double_escaped(proc)?,
|
||||
};
|
||||
};
|
||||
// `process_tag` will require closing tag.
|
||||
chain!(proc.match_while_not_seq(SCRIPT_END).keep());
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue