-
-
Save chowey/2760201 to your computer and use it in GitHub Desktop.
Simple optimization of Jade attrs
This file contains hidden or 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
self = | |
{ | |
header: "Header", | |
header2: "Header2", | |
header3: "Header3", | |
header4: "Header4", | |
header5: "Header5", | |
header6: "Header6", | |
list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] | |
}; | |
attrs1 = function (obj, escaped) { | |
var terse = obj.terse; | |
delete obj.terse; | |
var keys = Object.keys(obj) | |
, len = keys.length; | |
var s = ' '; | |
if (len) { | |
for (var i = 0; i < len; ++i) { | |
var key = keys[i] | |
, val = obj[key]; | |
if ('boolean' == typeof val || null == val) { | |
if (val) { | |
terse | |
? (s+= key + ' ') | |
: (s+= key + '="' + key + '" '); | |
} | |
} else if (0 == key.indexOf('data') && 'string' != typeof val) { | |
s += key + '="' + JSON.stringify(val) + '" '; | |
} else if ('class' == key && Array.isArray(val)) { | |
s += key + '="' + exports.escape(val.join(' ')) + '" '; | |
} else if (escaped[key]) { | |
s += key + '="' + exports.escape(val) + '" '; | |
} else { | |
s += key + '="' + val + '" '; | |
} | |
} | |
} | |
return s.substr(0, s.length-1); | |
}; | |
attrs2 = function (obj, escaped) { | |
var terse = obj.terse; | |
delete obj.terse; | |
var keys = Object.keys(obj) | |
, len = keys.length; | |
var s = ''; | |
if (len) { | |
for (var i = 0; i < len; ++i) { | |
var key = keys[i] | |
, val = obj[key]; | |
if ('boolean' == typeof val || null == val) { | |
if (val) { | |
terse | |
? (s+= ' ' + key) | |
: (s+= ' ' + key + '="' + key + '"'); | |
} | |
} else if (0 == key.indexOf('data') && 'string' != typeof val) { | |
s += ' ' + key + '="' + JSON.stringify(val) + '"'; | |
} else if ('class' == key && Array.isArray(val)) { | |
s += ' ' + key + '="' + exports.escape(val.join(' ')) + '"'; | |
} else if (escaped[key]) { | |
s += ' ' + key + '="' + exports.escape(val) + '"'; | |
} else { | |
s += ' ' + key + '="' + val + '"'; | |
} | |
} | |
} | |
return s; | |
}; | |
jt1 = function () | |
{ | |
//var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; | |
var buf = []; | |
//var self = locals || {}; | |
var interp; | |
buf.push('<div><h1'); | |
buf.push(attrs1({ "class": ('header') }, {})); | |
buf.push('>'); | |
var __val__ = self.header | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h1><h2'); | |
buf.push(attrs1({ "class": ('header2') }, {})); | |
buf.push('>'); | |
var __val__ = self.header2 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h2><h3'); | |
buf.push(attrs1({ "class": ('header3') }, {})); | |
buf.push('>'); | |
var __val__ = self.header3 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h3><h4'); | |
buf.push(attrs1({ "class": ('header4') }, {})); | |
buf.push('>'); | |
var __val__ = self.header4 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h4><h5'); | |
buf.push(attrs1({ "class": ('header5') }, {})); | |
buf.push('>'); | |
var __val__ = self.header5 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h5><h6'); | |
buf.push(attrs1({ "class": ('header6') }, {})); | |
buf.push('>'); | |
var __val__ = self.header6 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h6><ul'); | |
buf.push(attrs1({ "class": ('list') }, {})); | |
buf.push('>'); | |
// iterate self.list | |
(function() | |
{ | |
if ('number' == typeof self.list.length) | |
{ | |
for (var $index = 0, $$l = self.list.length; $index < $$l; $index++) | |
{ | |
var item = self.list[$index]; | |
buf.push('<li'); | |
buf.push(attrs1({ "class": ('item') }, {})); | |
buf.push('>'); | |
var __val__ = item | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</li>'); | |
} | |
} | |
else | |
{ | |
for (var $index in self.list) | |
{ | |
if (self.list.hasOwnProperty($index)) | |
{ | |
var item = self.list[$index]; | |
buf.push('<li'); | |
buf.push(attrs({ "class": ('item') }, {})); | |
buf.push('>'); | |
var __val__ = item | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</li>'); | |
} | |
} | |
} | |
}).call(this); | |
buf.push('</ul></div>');return new Buffer(buf.join("")); | |
} | |
jt2 = function () | |
{ | |
//var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; | |
var buf = []; | |
//var self = locals || {}; | |
var interp; | |
buf.push('<div><h1'); | |
buf.push(attrs2({ "class": ('header') }, {})); | |
buf.push('>'); | |
var __val__ = self.header | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h1><h2'); | |
buf.push(attrs2({ "class": ('header2') }, {})); | |
buf.push('>'); | |
var __val__ = self.header2 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h2><h3'); | |
buf.push(attrs2({ "class": ('header3') }, {})); | |
buf.push('>'); | |
var __val__ = self.header3 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h3><h4'); | |
buf.push(attrs2({ "class": ('header4') }, {})); | |
buf.push('>'); | |
var __val__ = self.header4 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h4><h5'); | |
buf.push(attrs2({ "class": ('header5') }, {})); | |
buf.push('>'); | |
var __val__ = self.header5 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h5><h6'); | |
buf.push(attrs2({ "class": ('header6') }, {})); | |
buf.push('>'); | |
var __val__ = self.header6 | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</h6><ul'); | |
buf.push(attrs2({ "class": ('list') }, {})); | |
buf.push('>'); | |
// iterate self.list | |
(function() | |
{ | |
if ('number' == typeof self.list.length) | |
{ | |
for (var $index = 0, $$l = self.list.length; $index < $$l; $index++) | |
{ | |
var item = self.list[$index]; | |
buf.push('<li'); | |
buf.push(attrs2({ "class": ('item') }, {})); | |
buf.push('>'); | |
var __val__ = item | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</li>'); | |
} | |
} | |
else | |
{ | |
for (var $index in self.list) | |
{ | |
if (self.list.hasOwnProperty($index)) | |
{ | |
var item = self.list[$index]; | |
buf.push('<li'); | |
buf.push(attrs({ "class": ('item') }, {})); | |
buf.push('>'); | |
var __val__ = item | |
buf.push(null == __val__ ? "" : __val__); | |
buf.push('</li>'); | |
} | |
} | |
} | |
}).call(this); | |
buf.push('</ul></div>');return new Buffer(buf.join("")); | |
} | |
var Benchmark = require('benchmark') | |
var suite = new Benchmark.Suite | |
suite | |
.add('jt1 - (attrs +,substr)', jt1) | |
.add('jt2 - (attrs +,prepend) ', jt2) | |
.on('cycle', function (event, bench) { | |
console.log(bench.toString()); | |
}) | |
.on('complete', function () { | |
console.log('Fastest is ' + this.filter('fastest').pluck('name')) | |
}) | |
.run(); |
This file contains hidden or 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
var Benchmark = require('benchmark'); | |
var suite = new Benchmark.Suite, | |
input = 'blockquote hello\n p World!\n'; | |
suite | |
.add('substr', function () { | |
var i = 3, s = ' '; | |
while (i--) { | |
s += input + '; '; | |
} | |
return s.substr(0, s.length - 1); | |
}) | |
.add('prepend', function () { | |
var i = 3, s = ''; | |
while (i--) { | |
s += ' ' + input + ';'; | |
} | |
return s; | |
}) | |
.on('cycle', function (event, bench) { | |
console.log(bench.toString()); | |
}) | |
.on('complete', function () { | |
console.log('Fastest is ' + this.filter('fastest').pluck('name')); | |
}) | |
.run(); |
SubstrPrependBench.js
substr x 4,607,894 ops/sec ±3.05% (57 runs sampled)
prepend x 24,530,811 ops/sec ±2.70% (57 runs sampled)
Fastest is prepend
The SubstrPrependBench.js is a better direct measure of doing three concats per loop instead of two concats plus a substr at the end.
JadeAttrsBench.js shows it in action with the rest of the stuff.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
JadeAttrsBench.js