Skip to content

Instantly share code, notes, and snippets.

@chowey
Forked from saabi/JadeTmpltBench.js
Created May 21, 2012 01:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chowey/2760201 to your computer and use it in GitHub Desktop.
Save chowey/2760201 to your computer and use it in GitHub Desktop.
Simple optimization of Jade attrs
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();
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();
@chowey
Copy link
Author

chowey commented May 21, 2012

JadeAttrsBench.js

jt1 - (attrs +,substr) x 35,110 ops/sec ±5.05% (51 runs sampled)
jt2 - (attrs +,prepend)   x 39,391 ops/sec ±4.12% (56 runs sampled)
Fastest is jt2 - (attrs +,prepend)

@chowey
Copy link
Author

chowey commented May 21, 2012

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

@chowey
Copy link
Author

chowey commented May 21, 2012

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